• Advertisement
Sign in to follow this  

how safe is using #pragma once

This topic is 4870 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I hate defining _HEADER_NAME_H_ for every header file. #pragma once IMO is much cleaner. It used to be MSVC++ specific, and I heard gcc has implemented it too. I am not sure with the other compilers. So, can it now be considered as a standard preprocessor command?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by alnite
I hate defining _HEADER_NAME_H_ for every header file.

17.4.3.1.2:
Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the [compiler implementors] for any use.
Quote:

#pragma once IMO is much cleaner. It used to be MSVC++ specific, and I heard gcc has implemented it too. I am not sure with the other compilers.

So, can it now be considered as a standard preprocessor command?

No. However, if those are the only compilers you are going to target, feel free to use #pragma once

Share this post


Link to post
Share on other sites
No, it can't ben considered a standard command just because one or two compilers support it. For example, if you went to use your code with SN Systems compiler for PS2, it probably won't work. Same thing Metroworks compiler for various console systems.

If you have no desire to move your code base to anything other than Windows then do what you want. But, I wouldn't count on it working everywhere.

Personally, I try to use the least amount of platform specific stuff simply so that it's easier to re-use no matter when/where I want to use it. Each to their own though...

-John

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by alnite
I hate defining _HEADER_NAME_H_ for every header file. #pragma once IMO is much cleaner. It used to be MSVC++ specific, and I heard gcc has implemented it too. I am not sure with the other compilers.


Pretty much everyone uses include guards. Clean or not, nobody will be confused by them, and nobody will fault you for using them.

Quote:

So, can it now be considered as a standard preprocessor command?


No, a pragma is per definition not standard, but the standard allows use of any pragmas, as compilers are supposed to ignore pragmas they don't understand. Herein lies the problem... If you have used #pragma once instead of include guards, the whole semantic of the program has changed. A compiler that has no #pragma once will ignore it, and there will be no inclusion guards in place. Your program will essentially be broken C++. It's up to you if you want to be that anal or not. For the code to be valid C++, use either include guards alone or #pragma once along with them.

I also have a vague recollection that #pragma once also does not guarantee that a file will not be included more than once, just that it will only be read once.

Share this post


Link to post
Share on other sites
This issue is a matter of opinion, and here's my opinion: Since it's really very rare that you will switch compilers during a project, I say just use #pragma once. It definitely is cleaner. (and it's easy to fix in that rare situation where you do switch compilers.)

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Depends on your definition of clean. IMHO pragmas are about the only thing that are dirtier than regular preprocessor options.

Share this post


Link to post
Share on other sites
Quote:
Original post by pinacolada
This issue is a matter of opinion, and here's my opinion: Since it's really very rare that you will switch compilers during a project, I say just use #pragma once. It definitely is cleaner. (and it's easy to fix in that rare situation where you do switch compilers.)

Yes, your co-workers will thank you for your forsight on using #pragma once when they have to go through and change all of your silly headers.

Share this post


Link to post
Share on other sites
Quote:
Original post by pinacolada
This issue is a matter of opinion, and here's my opinion: Since it's really very rare that you will switch compilers during a project, I say just use #pragma once. It definitely is cleaner. (and it's easy to fix in that rare situation where you do switch compilers.)

Y'know what'd be easier to fix? Using include guards! Do you know why? Because there'd be nothing to fix!

Share this post


Link to post
Share on other sites
Quote:
Original post by Washu
Quote:
Original post by pinacolada
This issue is a matter of opinion, and here's my opinion: Since it's really very rare that you will switch compilers during a project, I say just use #pragma once. It definitely is cleaner. (and it's easy to fix in that rare situation where you do switch compilers.)

Yes, your co-workers will thank you for your forsight on using #pragma once when they have to go through and change all of your silly headers.


Oh yeah, cause we're *definitely* going to migrate to a non-MS compiler in the future. We only just upgraded from VC6 to VC.net two weeks ago.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
And if your company decides to sell a source code license to someone, who perhaps uses borland or something else? Will they be pleased?

Share this post


Link to post
Share on other sites
Quote:
Original post by pinacolada
Oh yeah, cause we're *definitely* going to migrate to a non-MS compiler in the future. We only just upgraded from VC6 to VC.net two weeks ago.

Yes, well, I have seen it before. I've also seen projects which are required to compile on more platforms than one or two. Some of which use compilers which don't support #pragma once. Go for the generic solution. It's just as readable, and much more portable.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Yeah, and if you think it's too much to type, learn to touch type.

Share this post


Link to post
Share on other sites
OK...FIRST OFF!

Washu, I think you are very, very secksy.

SECOND OFF!

What the heck is "touch-typing"? Is it what I'm doing now, where you learn to type by, uh...learning where the keys are? If that's touch typing, what other kinds of typing are there (aside from "keypecking")?

I hear the term a lot, but I'm usually too busy watching my words scroll by on-screen to listen.

Share this post


Link to post
Share on other sites
Or get a half decent IDE that puts header guards in for you automatically. This also has the bonus that the IDE usually knows not to use reserved identifiers in header guards, so your program will be even more standards conforming.

Share this post


Link to post
Share on other sites
We used several files between XBox, PC, and PS2 versions of Trivial Pursuit: Unhinged, and we had no issues. Know why? We used standard C++ instead of quick platform specific hacks.

Some other companies even get to throw GameCube into the mix. Perhaps some libraries of game logic can even be included in GBA products, and the new PSP. Perhaps like iD, you'd like to have a Linux version, or Linux servers. Perhaps you'd like a quick port to the Mac.

Maybe you'll be hired to do firmware for custom hardware with obscure cross compilers. I've had a few of these jobs. At one such job the same code compiled for DOS with simulated hardware interfaces, allowing us to test code a year before the hardware was ready. Later, the DOS emulator was moved to Windows. So here, with one product with one target platform, it was useful to have the code compiling and running on 3 platforms during development.

Stop being lazy and short-sighted.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
It's not a bad idea to use both mechanisms in the same header.
The pragma may reduce build times for compilers that support it.

Regards,

Share this post


Link to post
Share on other sites
#pragma once is one of my favourite heretical C++ <s>features</s> extensions, if only because of its reputation for potential catastrophe.

Heretical or not, #pragma once is simpler, and by extension, more readable and less error prone. The price you pay is being limited to MSVC and GCC, but that's not such a heavy price for some. :)

Share this post


Link to post
Share on other sites
Jeez, it's hard to believe such a trivial issue is getting argued into the ground! I must have touched a nerve.

For the record, here is what I don't like about include guards:
1) looks ugly
2) it puts a random #endif at the bottom of your file. Someone who doesn't know any better can look at that #endif, and go WTF?
3) once or twice in the past, I've created a new class by duplicating an old file, but forgot to change the include guard, which inevitably caused massive errors. #pragma once doesn't do that.

And considering that it's SO TRIVIAL to change between them, it only takes the tiniest bit of inconvenience to tip the scales in favor of one or the other. If using #pragma once added 2 seconds to the time it takes to build, then I would use include guards. Also when I am in any of the situations listed above (like writing code for mulitple platforms), I use include guards.

As far as being lazy, haven't you heard that in computer science, laziness is a virtue?

Share this post


Link to post
Share on other sites
Wuah, so many replies. The reason why I ask this is because I am trying to avoid name conflicts. Normally, I would define every header as HEADERNAME_H. Then when I started using directories to organize my project files, I ended up with two/more files with the same name. To avoid it, I started putting the namespace/projectname/directory in front of it: NAMESPACE_HEADERNAME_H.

This worked OK until I started reusing my classes for several other projects. It's just annoying to see some other unrelated project names defined in the projects I am working on. So, I had to change every one of them and each change reminds me of using the convenient #pragma once, but for portability sakes, I insisted on using include guards.

Now, I am trying to have some general-purpose classes that I can reuse over and over again without changing the names; and the only way to do that is to come up with generic names. However, the more generic your names are, the more they will conflict with other names. I don't want to spend some amount of time just to come up with some unique include names.

Share this post


Link to post
Share on other sites
Quote:
Original post by pinacolada
Jeez, it's hard to believe such a trivial issue is getting argued into the ground! I must have touched a nerve.

For the record, here is what I don't like about include guards:
1) looks ugly
2) it puts a random #endif at the bottom of your file. Someone who doesn't know any better can look at that #endif, and go WTF?
3) once or twice in the past, I've created a new class by duplicating an old file, but forgot to change the include guard, which inevitably caused massive errors. #pragma once doesn't do that.



I've been the recipient of the task of having to change #pragma once calls in a code base to use include guards. Over two thousand source files! I ended up writing a script to do it, but it pissed me off to no end.

To your points.

1. Looks ugly? That's subjective - I think it looks nice and professional.

2., random endif? code it like this



#ifdef _INCLUDE_GUARD_H_
#define _INCLUDE_GUARD_H_

// ...

#endif // _INCLUDE_GUARD_H_



The trailing comment makes it pretty clear what you are doing.

3. If you have cut and paste errors like this, I'm sure you'll have other cut and paste problems - just add include guards to the list of things to check for when you are doing a cut and paste coding job.


I find include guards are more verbose, and make more sense then a #pragma once hanging around anywhere in the header. Include guards MUST be around everything in the file, pragmas can be ANYWHERE in the file. People migrating from embedded systems or console development to MSVC won't have any idea what they are looking at, and you'll end up with the two types of systems in your files. Stick with the one that provides the greatest compatiblity.

- S

Share this post


Link to post
Share on other sites
Quote:
Original post by pinacolada
Jeez, it's hard to believe such a trivial issue is getting argued into the ground! I must have touched a nerve.

For the record, here is what I don't like about include guards:
1) looks ugly
2) it puts a random #endif at the bottom of your file. Someone who doesn't know any better can look at that #endif, and go WTF?

Okay. This is quite simple. Anyone who looks at an #endif at the end of a header file and is confused shouldn't be programming in C/C++! Ever!
Quote:

3) once or twice in the past, I've created a new class by duplicating an old file, but forgot to change the include guard, which inevitably caused massive errors. #pragma once doesn't do that.

Massive errors? An error that can be fixed by changing two lines of code is a "massive error"?
Quote:

And considering that it's SO TRIVIAL to change between them, it only takes the tiniest bit of inconvenience to tip the scales in favor of one or the other.

It's non-trivial enough that I don't want the inconvenience.
Quote:

If using #pragma once added 2 seconds to the time it takes to build, then I would use include guards. Also when I am in any of the situations listed above (like writing code for mulitple platforms), I use include guards.

You never heard of planning ahead?
Quote:

As far as being lazy, haven't you heard that in computer science, laziness is a virtue?

Yes, but that's a lie. The virtue is in doing work today that allows one to be lazy tomorrow.

Once you've written a guard, you never have to change it. Once you've written a #pragma, you may well have to change it, or someone else will.

Given that, as you say, that it "takes like 2 seconds" to change it, why not do a little extra work today safe in the knowledge that a lifetime of laziness awaits you?

Share this post


Link to post
Share on other sites
Of course, the fact that people even have to have a discussion about a topic like this, is symptomatic of just how brain damaged C/C++ really is.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
How about using the #pragma and placing a compiler check in some major header file like this:

#ifndef _MSVC (whatever this constant for MS compilers is)
#error WARNING, ALL PRAGMAS MAY NOT FUNCTION CORRECTLY
#endif

Share this post


Link to post
Share on other sites
If you're using VC, why not make a macro? With just a few simple keypresses I can add the include guards, and put my author info at the top of my file. The guard is of the format:

#ifndef INCLUDED_BLAH_HPP_<time>_
#define INCLUDED_BLAH_HPP_<time>_
...
#endif // INCLUDED_BLAH_HPP_<time>_

Adding the time ensures that I don't need to worry about two files with the same name clashing. If you really want #pragma once, you can easily add it add as well.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Arild Fines
... just how brain damaged C/C++ really is.


That's why the only sane way of doing C++, is to use standard features whenever it is possible, even if it means a little more work up front. If you use something nonstandard (like pragma once) and it fails at some point, YOU take the blame. If it fails while being standard conformant, someone else (like the compiler vendor) gets the blame.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement