【问题标题】:Indicate C++ standard in source in a standard way以标准方式在源代码中指示 C++ 标准
【发布时间】:2014-10-14 09:48:59
【问题描述】:

符合标准的 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= 的适当参数(cf. shebang's which 可以指明脚本语言/版本:#!/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++ 等价物: &lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;

【问题讨论】:

  • 出于兴趣,你为什么要关心?如果您编写可在 98 中编译的代码,它应该在 03 或 11 中可编译(您可能正在使用已弃用的函数 - 可能),但它应该编译 - 那么目的是什么?
  • @Nim 我猜这是关于文件请求的最低版本
  • @leemes,让我换个方式问这个问题,如果一个文件说它可以用 98 编译,std= 是否会更改为该文件的那个?如果不是,那么这种方法没有意义恕我直言,在项目级别决定您使用哪个版本,并可能检查文件以处理旧编译器(如果它太旧则拒绝......)
  • @Nim 我有一个构建脚本,我想自动检测我的源代码是否使用 C++11,所以我不必关心设置适当的 -std 标志。通常你可以强制执行编译器的最新标准,例如-std=c++11 但严格来说,C++11 标准有一些向后不兼容的变化。总的来说,我认为它作为文档很好(例如,C++ 标头通常以 '.h' 结尾,因此除非您手动检查它们,否则 C 标头可能会有些混淆)
  • 有一个标准化功能请求的提案,看看here

标签: c++ c++11 compilation


【解决方案1】:

C++ 标准在某种程度上有点像针对库进行开发。从这个意义上说,库通常以缓慢弃用旧功能的方式发展,同时访问新功能。典型的方法是引入新方法或签名,同时仍允许访问旧方法或签名。

举个简单的例子,例如,您可以为 iPhone 制作一个向后兼容 IOS 4 及更高版本的应用程序。您无法选择要支持的特定版本。这很好,因为否则你会打开代码进化到一个可能性矩阵,使你的代码更难理解和维护。

或者,您可以引入预处理器指令以根据某种版本或标志有条件地构建某些片段。然而,这些都是临时措施,应该随着代码的发展而被删除。

所以我认为要按原样回答这个问题,更好的问题是在这种情况下问自己,添加这样的东西实际上会解决什么问题,会不会增加不必要的复杂性(其中一种代码味道不好设计)?

在这种情况下,根据经验,我个人认为你最好坚持一个标准。我想你会发现,试图通过使用各种预处理器#ifdef 和#ifndefs 来区分标准会使理解你的代码库变得难以理解和管理。即使您有一个包含文件,其中定义了允许由所有其他文件包含的版本,它也会成为另一个需要管理的文件......更不用说当您更改它时,您必须重新编译包含它的所有内容。

如果您担心有人使用错误的标准构建您的代码库,请使用不需要开发人员输入该信息的构建系统。例如 Make、Ant、cmake。它使您的软件的构建变得简单,并且清楚地定义了应该如何以可重复的方式编译项目。如果你走这条路,你会发现试图保护代码不被不正确地编译不是问题。

此外,如果他们不按常理使用错误的标准进行编译,他们会遇到大量编译器错误 =)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-21
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 2012-03-29
    • 2011-07-24
    • 2013-12-17
    相关资源
    最近更新 更多