#ifndef _FOO_H #define _FOO_H //header code here #endif //_FOO_H
#pragma once
Started by Tarviathun, Jan 17 2005 10:43 PM
13 replies to this topic
#1 Members - Reputation: 152
Posted 17 January 2005 - 10:43 PM
In my computer science class(C++), my professor made a big deal about making sure that headers weren't included more than once. He made everyone define a constant for their headers. The code looked like this:
Is there any functional/practical difference between this and #pragma once? Or am I being a complete idiot and asking about things of which I know nothing? :)
Sponsor:
#2 Members - Reputation: 754
Posted 17 January 2005 - 10:48 PM
AFAIK "#pragma once" belongs to Microsoft specific. Hence it's not recognized by other compilers.
"#ifndef ..." are ANSI, so they are ok.
Cheers.
/def
EDIT: I remember using "#pragma once" in g++. It didn't crash, only said something about it being obsolete... I don't know what it meant by this...
"#ifndef ..." are ANSI, so they are ok.
Cheers.
/def
EDIT: I remember using "#pragma once" in g++. It didn't crash, only said something about it being obsolete... I don't know what it meant by this...
#3 Staff Emeritus - Reputation: 1668
Posted 17 January 2005 - 10:53 PM
#pragma once is Microsoft-specific (it is deprecated on GCC), but it also has a different effect than inclusion guards. #pragma once instructs the preprocessor to open and parse the file only once, whereas inclusion guards simply cause an empty text substitution when compositing the compilation units. (MSDN)
Easy on the swear words, eh?
Easy on the swear words, eh?
#4 Members - Reputation: 250
Posted 17 January 2005 - 11:18 PM
#pragma once is far more pleasant to use. It has been undeprecated in the more recent versions of gcc (on older versions it works but gives a warning), and may exist in some other compilers as well, but it isn't standard for all c/c++ compilers. Feel free to use it if you're writing specifically for gcc or vc, but be careful if you want your code to work on every compiler under the sun. #ifndef/#define/#endif is much safer in those cases.
#6 Members - Reputation: 336
Posted 18 January 2005 - 02:00 AM
Quote:
Original post by robinei
What about using both? Is it necessary to conditionally include the #pragma depending on compiler or will compilers who don't support it just ignore it?
Edit: And what are the defines that can be used to reliably for check for GCC or VC?
Well, here's how Valve did it:
Quote:
Originally found in Half Life 2 source code file "BaseEntity.h"
#ifndef BASEENTITY_H
#define BASEENTITY_H
#ifdef _WIN32
#pragma once
#endif
//Rest of BaseEntity.h
#endif
which doesn't check for the compiler per se, but it pretty much means Valve says "If we're compiling for Windows, we're using VC. If we're compiling for Linux, etc, we're using something that doesn't support #pragma once"
Use what you are required to use (for the OP that means the #ifndef), or if you have no requirements use what you want.
#7 Members - Reputation: 982
Posted 18 January 2005 - 02:35 AM
Beware, #pragma once doesn't guarantee single inclusion (it could be fooled on VC5 with relative paths, IIRC).
It was meant as an optimization that adds the current include file to a compiler table, so that the file won't be opened again later. Newer compilers are clever enough to do the same when they see standard include guards.
The MS CRT sources show correct use: they have standard include guards and #pragma once.
robinei: Unknown pragmas are ignored but may raise warnings.
__GNUC__ and _MSC_VER identify GCC and VC.
Tarviathun: use the search function! This has already been explained multiple times.
It was meant as an optimization that adds the current include file to a compiler table, so that the file won't be opened again later. Newer compilers are clever enough to do the same when they see standard include guards.
The MS CRT sources show correct use: they have standard include guards and #pragma once.
robinei: Unknown pragmas are ignored but may raise warnings.
__GNUC__ and _MSC_VER identify GCC and VC.
Tarviathun: use the search function! This has already been explained multiple times.
#8 Members - Reputation: 226
Posted 18 January 2005 - 06:13 AM
All #pragma directives are compiler-specific, that's why they're pragmas. There may be some overlap (like GCC supporting MS's 'once' pragma) but the purpose of #pragma is that it's for compiler-specific directives. From this, you can infer that any other directives you see should be compiler-generic.
Pragma Directives
Pragma Directives
#9 Members - Reputation: 152
Posted 18 January 2005 - 09:54 AM
Thanks all for the help.
Jan, sorry to bug you. I don't mean to keep asking the same things. I did look, but I didn't find anything.
I think for now I'll stick with the non-pragma method. Since I'm attempting to be non-platform/API specific in my current project, I think it'd be good to go the safe route of a well-used standard.
Jan, sorry to bug you. I don't mean to keep asking the same things. I did look, but I didn't find anything.
I think for now I'll stick with the non-pragma method. Since I'm attempting to be non-platform/API specific in my current project, I think it'd be good to go the safe route of a well-used standard.
#10 Crossbones+ - Reputation: 402
Posted 18 January 2005 - 10:11 AM
I use this convention (obviously in addition to include guards):
Not only do you check to make sure you're using a compiler that supports it, but you're checking to make sure that it's a sufficient version. Not to mention that the platform check is implicit.
#if _MSC_VER >= 1200
#pragma once
#endif
Not only do you check to make sure you're using a compiler that supports it, but you're checking to make sure that it's a sufficient version. Not to mention that the platform check is implicit.






