Why isn't C/C++'s “#pragma once” an ISO standard?

前端 未结 9 1652
说谎
说谎 2020-11-28 11:29

I am currently working on a big project and maintaining all those include guards makes me crazy! Writing it by hand is frustrating waste of time. Although many editors can g

相关标签:
9条回答
  • 2020-11-28 12:06

    I think right way to allow to do multiple include with special pragma only and disallow to multiple include by default for example:

    #pragma allow_multiple_include_this_file
    

    So since you asked why. Did you send your proposal to standart developers? :) I'm not send too. Can one be a reason?

    0 讨论(0)
  • 2020-11-28 12:07

    A pragmatic solution:

    1) choose some consistent guard-naming policy (e.g. path relative to project root + file name, or whatever else you choose). Include possible exceptions for third-party code.

    2) write a program (a simple python script would do) to walk recursively the source tree and verify that the guards all conformal to the policy. And whenever the guards are wrong, output a diff (or sed script, or whatever else) that the user can easily apply to fix. Or just ask for a confirmation and make changes from the same program.

    3) make everyone on the project use it (say, before submitting to source control).

    0 讨论(0)
  • 2020-11-28 12:10

    As was already noted, C++ Standard should account for different development platforms some of which may have limitations making #pragma once support impossible to implement.

    On the other hand, support for threads was not added for the similar reason previously, but newer C++ Standard includes threads nevertheless. And in the latter case we may cross-compile for a very limited platform, but development is done on a full-fledged platform. Since GCC supports this extension, I think, the real answer to your question is that there is no interested party in pushing this feature into C++ Standard.

    From practical standpoint, include guards caused our team more trouble than the incompliance of #pragma once directive. For instance, GUID in include guards do not help in case if file is duplicated and later both copies are included. When using only #pragma once we get duplicate definition error and can spend time unifying source code. But in case of include guards the problem may require run-time testing to catch, e.g. this happens if copies differ in default arguments for function parameters.

    I avoid using include guards. If I have to port my code to a compiler without #pragma once support, I will write a script which will add include guards to all header files.

    0 讨论(0)
  • The problem occurs when you have headers with the same filename in different directories.

    So you have two headers which are both called ice_cream_maker.h in your project, both of which have a class called ice_cream_maker defined in them which performs the same function? Or are you calling every class in your system foo?

    Nevertheless definition is included once, compiler still opens header every time it meets header inclusion.

    Edit the code so you don't include headers multiple times.

    For dependent headers (rather than the main header for a library), I often use header guards which are like this:

    #ifdef FOO_BAR_BAZ_H
    #error foo_bar_baz.h multiply included
    #else
    #define FOO_BAR_BAZ_H
    
    // header body
    
    #endif
    
    0 讨论(0)
  • 2020-11-28 12:12

    IIRC, #pragma anything is not part of the language. And it shows up in practice, a lot.

    (edit:completely agree that the inclusion and linking system should have been more of a focus for the new standard as it is one of the most obvious weaknesses, in 'le this day and age' )

    0 讨论(0)
  • 2020-11-28 12:17
    1. How often do you have to add an include file to this project? Is it really so hard to add DIRNAME_FILENAME to the guard? And there is always GUIDs.
    2. Do you really rename files that often? Ever? Also, putting the GUARD in the #endif is just as annoying as any other useless comment.
    3. I doubt your 1000 header files guard defines are even a small percentage of the number of defines generated by your system libraries (especially on Windows).
    4. I think MSC 10 for DOS (20+ years ago) kept track of what headers were included and if they contained guards would skip them if included again. This is old tech.
    5. namespaces and templates should not span headers. Dear me, don't tell me you do this:

      template <typename foo>
      class bar {
      #include "bar_impl.h"
      };
      
    6. You said that already.

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