简体   繁体   English

以标准方式在源中指示C ++标准

[英]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 : 符合标准的C ++编译器定义了一个__cplusplus宏,可以在预处理期间检查它以确定正在编译文件的标准, 例如

#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 ). 这将允许构建工具在编译之前检查源,以确定-std=的适当参数( 参见 shebang,它可以指示脚本语言/版本: #!/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: 我能想到的非标准和脆弱的方法是寻找__cplusplus的预处理器检查,但在上面的例子中我也可以写:

#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. 虽然我同情@Gary的答案,建议依赖于构建系统,但它假设我们实际上将有一个构建步骤。

But you can already today: 但你今天已经可以了:

  • use an interpreter to run a C++ program using eg CINT 使用解释器使用例如CINT运行C ++程序
  • or use a source to source translation using eg rosecompiler 或者使用源代码来使用例如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). 我的问题还在于表明源代码是C ++以及它的目的是什么版本(想象有人在70年后挖掘出我的代码,当时C ++可能像Cobol今天那样受欢迎)。

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"> 我想我要找的同样的东西是HTML的C ++ equiavlent: <!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. C ++标准在某种程度上有点像针对库开发。 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. 例如,您可以为iPhone制作一个向后兼容IOS 4及更高版本的应用程序。 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. 我认为你会发现通过使用各种预处理器#ifdef和#ifndefs来尝试区分标准将会使你理解你的代码库难以理解和管理。 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. 例如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 =) 此外,如果他们不顾一切地使用错误的标准进行编译,他们将受到大量编译器错误的欢迎=)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM