Indicate C++ standard in source in a standard way

Standard compliant C++ compilers define a __cplusplus macro which may be inspected during preprocessing to determine under what standard a file is being compiled, eg:

#if __cplusplus < 201103L
#error "You need a C++11 compliant compiler."
#endif

#include <iostream>
#include <vector>

int main(){
    std::vector<int> v {1, 2, 3};
    for (auto i : v){
        std::cout << i << " ";
    }
    std::cout << std::endl;
    return 0;
}

My question is:

  • Is there a standard way to indicate what standard a source file should be compiled with?
  • That would allow build tools to inspect sources prior to compilation to determine the appropriate argument for -std= (cf. shebang's which can indicate scripting language/version: #!/usr/bin/env python3 ).

    A non standard and brittle way I can think of is looking for the preprocessor checks of __cplusplus but in the example above I could also have written:

    #if __cplusplus <= 199711L
    #error "You need a C++11 compliant compiler."
    #endif
    

    hence, writing eg a regex would become quite tricky to catch all variations.

    EDIT:

    While I sympathize with the answer by @Gary which suggests relying on a build system, it assumes that we actually will have a build step.

    But you can already today:

  • use an interpreter to run a C++ program using eg CINT
  • or use a source to source translation using eg rosecompiler
  • My question is also about indicating that the source is C++ and what version it was intended for (imagine someone digging out my code 70 years from now when C++ might be as popular as say Cobol is today).

    I guess the equivalent thing I would be looking for is the C++ equiavlent of HTML's: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">


    C++ Standards in a way are somewhat like developing against a library. In that sense, libraries typically evolve in a way that slowly deprecates old functions while making access to new functions. The typical way is the introduction of new methods or signatures while still allowing access to the old ones.

    As a simple example, for instance, you might make an app for the iPhone that is backwards compatible with IOS 4 and above. You don't get the option to cherry pick what specific versions you want to support. This is good because otherwise you open code evolution up to a matrix of possibilities, making your code harder to understand and maintain.

    Alternatively, you may introduce preprocessor instructions to build certain pieces conditionally depending on a version or flag of some sort. These are temporary measures, however, and should be removed as the code evolves.

    So I think for answering this question as is, the better question is asking oneself in this situation is what will adding something like this actually solve and will it add needless complexity (one of the code smells of bad design)?

    In this situation and from experience, I personally think you're better sticking with one standard. I think you'll find that trying to differentiate standards by sprinkling various preprocessor #ifdef and #ifndefs is going to make understanding your code base difficult to understand and manage. Even if you had one include file with the definition of what version is allowed that gets included by all other files, it becomes yet another file to manage....not to mention when you change it you have to recompile everything that includes it.

    If you're worried about someone building your code base with the wrong standard, use a build system that doesn't require developers to input that information. For instance Make, Ant, cmake. It makes the building of your software simple and clearly defines how the project should be compiled in a repeatable fashion. If you go this route, you'll see that trying to protect the code from being compiled improperly becomes a non-issue.

    Also, if they go out of their way and compile with the wrong standard, they'll be greeted with plenty of compiler errors =)

    链接地址: http://www.djcxy.com/p/23054.html

    上一篇: Linux内核:静态常量vs #Define

    下一篇: 以标准方式表示源代码中的C ++标准