#pragma once versus #ifndef

I've heard that these are essentially the same:

1
2
3
4
5
6
//Automobile.h
#ifndef _AUTOMOBILE_H
#define _AUTOMOBILE_H
#else
//...
#endif 

vs
1
2
3
//Automobile.h
#pragma once
//... 


I've used the first way ("#ifndef") in the past... but "#pragma once" seems simpler and less lines to type and whatnot so I'm wondering if it's legit.

Thanks.
Pragmas are machine- or operating system-specific by definition, and are usually different for every compiler. So if you want your code to be portable use the first method.
I've always used both. That way, if #pragma once is supported, it will include the file only once but if not, it is ignored and will used the #ifndef method. I wonder if that would be redundant...?
The #ifndef version is wrong.
1
2
3
4
5
6
//Automobile.h
#ifndef _AUTOMOBILE_H
#define _AUTOMOBILE_H
//#else
//...
#endif  
@Zhuge it is redundant since all compilers support the include guard via #ifndef.
#pragma once can fail if the file system contains links to the same file that the compiler cannot follow.

For example, NTFS5 (Windows) supports hard links, but you can't detect that files are linked if you access the file system across an (SMB) network.
Last edited on
Not only should you use a unique and predictable (internal) include guard but you should also consider using (external) include guards around each preprocessor include directive in header files.

The following is a small example, both a.h and b.h include base.h but preprocessor will have information to not even visit base.h a second time. It makes little difference on a small project, but a large difference on big ones.

1
2
3
4
5
6
7
8
9
10
11
// a.h
#ifndef INCLUDED_A
#define INCLUDED_A

#ifndef INCLUDED_BASE
#include "base.h"
#endif

//code

#endif 


1
2
3
4
5
6
7
8
9
10
11
// b.h
#ifndef INCLUDED_B
#define INCLUDED_B

#ifndef INCLUDED_BASE
#include "base.h"
#endif

//code

#endif 


1
2
3
4
5
6
7
// base.h
#ifndef INCLUDED_BASE
#define INCLUDED_BASE

//code

#endif 


That just sounds too redundant in my book. I guess the file would not need opened at compile time, but that can't gain much...am I missing something?
I have to say, I don't see how that double guarding makes any difference whatsoever.
Borland's Turbo Vision (a C++ Text GUI Framework) uses the double guarded style, and so does GNU's autoconfig, although that style uses HAS_xxx, where HAS_xxx is externally defined.
As I said, on small projects you will see not much of a difference.

When the preprocessor is doing it's business and finds an #include, it goes off loads the included file and reads the first line. It finds the guard definition and has a look to see if it is already defined. If it is it still has to process the file until it finds the corresponding #endif and then carry on processing the file to the end.

You may find that your compiler has include guard optimisation, but I have seen results that suggest this can be improved upon.

Feel free to search the net for "external include guards", I have also seen them referred to as "redundant include guards". You should see various peoples experiment results.
Oh! So it reduces compile time. I somehow thought you meant it protected against cyclic inclusion or something.
Last edited on
My bad, I thought that I had said it is to reduce compile time.
Still, not worth it, in my opinion. It clutters the code for hardly any benefit.
Topic archived. No new replies allowed.