Is #pragma once a safe include guard?

2018-12-31 14:18发布

I've read that there is some compiler optimization when using #pragma once which can result in faster compilation. I recognize that is non-standard, and thus could pose a cross-platform compatibility issue.

Is this something that is supported by most modern compilers on non-windows platforms (gcc)?

I want to avoid platform compilation issues, but also want to avoid the extra work of fallback guards:

#pragma once
#ifndef HEADER_H
#define HEADER_H

...

#endif // HEADER_H

Should I be concerned? Should I expend any further mental energy on this?

14条回答
荒废的爱情
2楼-- · 2018-12-31 14:54

#pragma once does have one drawback (other than being non-standard) and that is if you have the same file in different locations (we have this because our build system copies files around) then the compiler will think these are different files.

查看更多
路过你的时光
3楼-- · 2018-12-31 14:54

I use it and I'm happy with it, as I have to type much less to make a new header. It worked fine for me in three platforms: Windows, Mac and Linux.

I don't have any performance information but I believe that the difference between #pragma and the include guard will be nothing comparing to the slowness of parsing the C++ grammar. That's the real problem. Try to compile the same number of files and lines with a C# compiler for example, to see the difference.

In the end, using the guard or the pragma, won't matter at all.

查看更多
听够珍惜
4楼-- · 2018-12-31 14:54

Additional note to the people thinking that an automatic one-time-only inclusion of header files is always desired: I build code generators using double or multiple inclusion of header files since decades. Especially for generation of protocol library stubs I find it very comfortable to have a extremely portable and powerful code generator with no additional tools and languages. I'm not the only developer using this scheme as this blogs X-Macros show. This wouldn't be possible to do without the missing automatic guarding.

查看更多
忆尘夕之涩
5楼-- · 2018-12-31 14:55

Using #pragma once should work on any modern compiler, but I don't see any reason not to use a standard #ifndef include guard. It works just fine. The one caveat is that GCC didn't support #pragma once before version 3.4.

I also found that, at least on GCC, it recognizes the standard #ifndef include guard and optimizes it, so it shouldn't be much slower than #pragma once.

查看更多
姐姐魅力值爆表
6楼-- · 2018-12-31 14:56

The main difference is that the compiler had to open the header file to read the include guard. In comparison, pragma once causes the compiler to keep track of the file and not do any file IO when it comes across another include for the same file. While that may sound negligible, it can easily scale up with huge projects, especially ones without good header include disciplines.

That said, these days compilers (including GCC) are smart enough to treat include guards like pragma once. i.e. they dont open the file and avoid the file IO penalty.

In compilers that dont support pragma I've seen manual implementations that are a little cumbersome..

#ifdef FOO_H
#include "foo.h"
#endif

I personally like #pragma once approach as it avoids the hassle of naming collisions and potential typo errors. It's also more elegant code by comparison. That said, for portable code, it shouldn't hurt to have both unless the compiler complains about it.

查看更多
孤独寂梦人
7楼-- · 2018-12-31 14:57

Not always.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52566 has a nice example of two files meant to both be included, but mistakenly thought to be identical because of identical timestamps and content (not identical file name).

查看更多
登录 后发表回答