以标准的方式在源代码中指示C++标准
Indicate C++ standard in source in a standard way
符合标准的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;
}
我的问题是:
- 是否有一种标准的方法来指示来源的标准文件是否应该编译
这将允许构建工具在编译之前检查源代码以确定-std=
(参见shebang的可以指示脚本语言/版本:#!/usr/bin/env python3
)。
我能想到的一种非标准且脆弱的方式是寻找预处理器检查__cplusplus
,但在上面的例子中,我可以也写过:
#if __cplusplus <= 199711L
#error "You need a C++11 compliant compiler."
#endif
因此,编写(例如正则表达式)要捕获所有变体将变得相当棘手。
编辑:
虽然我很同情@Gary的回答,他建议依赖构建系统,它假设我们实际上将有一个构建步骤。
但你今天已经可以了:
- 使用解释器运行C++程序,例如使用CINT
- 或者使用例如rosecompiler的源到源翻译
我的问题也是关于指出源代码是C++以及什么版本它是为(想象一下70年后有人挖出我的代码当C++可能像Cobol今天一样流行时)。
我想我要寻找的等价物是HTML的C++等价物:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
C++标准在某种程度上类似于针对库进行开发。从这个意义上说,库通常以一种在访问新函数的同时慢慢弃用旧函数的方式发展。典型的方法是引入新方法或签名,同时仍然允许访问旧方法或签名。
举个简单的例子,例如,你可以为iPhone制作一个向后兼容IOS4及以上版本的应用程序。您无法选择要支持的特定版本。这很好,因为否则你会将代码进化开放为一个可能性矩阵,使你的代码更难理解和维护。
或者,你可以引入预处理器指令,根据某种版本或标志有条件地构建某些部分。然而,这些都是临时措施,应该随着代码的发展而删除。
因此,我认为,在这种情况下,最好的问题是问问自己,添加这样的东西会真正解决什么问题,会增加不必要的复杂性吗(其中一个代码有糟糕设计的味道)?
在这种情况下,根据经验,我个人认为你最好坚持一个标准。我想你会发现,试图通过散布各种预处理器#ifdef和#ifndefs来区分标准会使理解你的代码库变得难以理解和管理。即使您有一个包含文件,其中定义了允许哪些版本被所有其他文件包含,它也会成为另一个需要管理的文件。。。。更不用说当你更改它时,你必须重新编译包括它在内的所有内容。
如果你担心有人用错误的标准构建你的代码库,那么使用一个不需要开发人员输入这些信息的构建系统。例如Make、Ant、cmake。它使软件的构建变得简单,并清楚地定义了如何以可重复的方式编译项目。如果你走这条路,你会发现试图保护代码不被错误编译是不成问题的。
此外,如果他们使用错误的标准进行编译,他们将遇到大量的编译器错误=)
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 铸造标准::有没有回到原来的类型
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 标准库类型的赋值运算符的引用限定符
- 标准是否严格定义了该程序应该如何编译?
- 如何从Windows应用程序输出到标准?
- 安全到标准:移动会员?
- 如何正确将字符串转换为标准::时间::system_clock::time_point?
- 这是否符合C++标准:双响双响,例如!!(-0.0).
- 标准::变体的赋值运算符
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 在编译指示包中包含标准地图会导致崩溃
- 在C++标准中,它在哪里指示用它所代表的源代码替换类别描述符的间隔协议
- 以标准的方式在源代码中指示C++标准