Link to home
Start Free TrialLog in
Avatar of CPOsosky
CPOsosky

asked on

Clarification on #pragma once

Just need something clarified...

#pragma once

Am I correct in assuming that the purpose of this
command is to physically allow a file to only be
opened once during compilation, in order to prevent
the same file from accidentally being compiled more
than once?

Thanks
    -Chris

Avatar of ckcheng091799
ckcheng091799

<!-- From MSDN -->

#pragma once

Specifies that the file, in which the pragma resides, will be included (opened) only once by the compiler in a build. A common use for this pragma is the following:

//header.h
#pragma once
// Your C or C++ code would follow:

Avatar of CPOsosky

ASKER

Thats nice.
Thats the same thing I found in the MSDN.
Now hows about answering my question? :) hmmmmmmmm?

-Chris
Hmmmmmmmmm ?
The wording is pretty clear :)
What else do you expect? "I swear, it is *really* opened only once!"
The main purpose of "#pragma once" is to allow to put code in the header file which otherwise would cause the linker to complain about doubly defined symbols, like:

// test.h

char szTest[] = "HALLO";

If this header is included twice, the linker will complain. It will not complain if you'd used "#pragma once".
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> The main purpose of "#pragma once" is to allow to put code in the header file which otherwise would
>> cause the linker to complain about doubly defined symbols, like:
That is a common missunderstanding.   It will not acheive that.  it will prevent the compiler from complaining about a duplicate symbol.   In this case if the header was included two times in the translation unit the szTest variable would be defined twice and would cause a compiler error. Using either an include gaurd or the once #pragma will prevent the compiler error, but that is the wrong solution.  it then sets ou up for the linker error.    The problem is that that variable is defined with external linkage.  And it is defined in that inclyude file.  If that include file is included into 2 or more translation units, then each translation unit will define that varaible.  Thus when they are linked together the linker will complain about duplicate definitions.  

If things have internal linkage, then you can use include gaurds or #pragma once to prevent duplicate deffinitons.   If they  have external linkage you cannot do that (sometimes it might work, but in general it won't).  Instead you mist never place a definition for somethign with external linkage in an include file.  The declaration goes in the include file and the definition goes into one source code file.  
Yes you're right (of course :-)

I haven't used #pragma once ever, and to be honest i can't understand why it works like it works.

If i got that right, you can accomplish #pragma once functionality by embracing the whole file with #ifndef XYZ, #define XYZ / #endif ?
If it is so, its only purpose is speeding up the compiling process?
And then: Couldn't this optimization be done by the compiler using a map of already included headers? If so, the whole #pragma once construct is a non-portable replacement for the #ifdef #define #endif block?
>> If i got that right, you can accomplish #pragma once functionality by
>> embracing the whole file with #ifndef XYZ, #define XYZ / #endif ?
right its a substitute for that more standard (and completely portable) technique.

>> If it is so, its only purpose is speeding up the compiling process?
Yes.  Its also more convenient than writting the $ifdef...#endif.    But its not portable to other compilers.

>> Couldn't this optimization be done by the compiler using
>> a map of already included headers?
I'm sure it is done that way, althougn not necessarily with a map.