Is #pragma once a safe include guard?

后端 未结 14 2356
青春惊慌失措
青春惊慌失措 2020-11-22 07:42

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

相关标签:
14条回答
  • 2020-11-22 07:53

    If we use msvc or Qt (up to Qt 4.5), since GCC(up to 3.4) , msvc both support #pragma once, I can see no reason for not using #pragma once.

    Source file name usually same equal class name, and we know, sometime we need refactor, to rename class name, then we had to change the #include XXXX also, so I think manual maintain the #include xxxxx is not a smart work. even with Visual Assist X extension, maintain the "xxxx" is not a necessary work.

    0 讨论(0)
  • 2020-11-22 07:54

    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.

    0 讨论(0)
  • 2020-11-22 07:54

    The performance benefit is from not having to reopen the file once the #pragma once have been read. With guards, the compiler have to open the file (that can be costly in time) to get the information that it shouldn't include it's content again.

    That is theory only because some compilers will automatically not open files that didn't have any read code in, for each compilation unit.

    Anyway, it's not the case for all compilers, so ideally #pragma once have to be avoided for cross-platform code has it's not standard at all / have no standardized definition and effect. However, practically, it's really better than guards.

    In the end, the better suggestion you can get to be sure to have the best speed from your compiler without having to check the behavior of each compiler in this case, is to use both pragma once and guards.

    #ifndef NR_TEST_H
    #define NR_TEST_H
    #pragma once
    
    #include "Thing.h"
    
    namespace MyApp
    {
     // ...
    }
    
    #endif
    

    That way you get the best of both (cross-platform and help compilation speed).

    As it's longer to type, I personally use a tool to help generate all that in a very wick way (Visual Assist X).

    0 讨论(0)
  • 2020-11-22 07:55

    Using '#pragma once' might not have any effect (it is not supported everywhere - though it is increasingly widely supported), so you need to use the conditional compilation code anyway, in which case, why bother with '#pragma once'? The compiler probably optimizes it anyway. It does depend on your target platforms, though. If all your targets support it, then go ahead and use it - but it should be a conscious decision because all hell will break loose if you only use the pragma and then port to a compiler that does not support it.

    0 讨论(0)
  • 2020-11-22 08:02

    Today old-school include guards are as fast as a #pragma once. Even if the compiler doesn't treat them specially, it will still stop when it sees #ifndef WHATEVER and WHATEVER is defined. Opening a file is dirt cheap today. Even if there were to be an improvement, it would be in the order of miliseconds.

    I simply just don't use #pragma once, as it has no benefit. To avoid clashing with other include guards I use something like: CI_APP_MODULE_FILE_H --> CI = Company Initials; APP = Application name; the rest is self-explanatory.

    0 讨论(0)
  • 2020-11-22 08:04

    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).

    0 讨论(0)
提交回复
热议问题