【问题标题】:Warning: range-based for loop is a C++11 extension警告:基于范围的 for 循环是 C++11 扩展
【发布时间】:2021-08-17 20:55:41
【问题描述】:

在 MacOS Big Sur 上尝试编译基于 for 循环的简单范围时,我收到了以下警告:

warning: range-based for loop is a C++11 extension [-Wc++11-extensions]

我尝试使用clang++g++,但都给出了相同的警告。有没有办法始终使用 C++11 进行编译,而无需使用 -std=c++11 且不使用别名?

编辑:我不想使用-std=c++11 的原因是因为我希望编译器默认为 C++11 或更高版本。

【问题讨论】:

  • 嗯,范围循环是 C++11 的特性,所以没有。 -std=c++11 怎么了?
  • "无需使用-std=c++11" - 为什么?如果您的编译器默认为您不想使用的 C++ 版本,为什么不指定您想要使用的版本?
  • 有没有办法始终使用 C++11 进行编译,而无需使用 -std=c++11 且不使用别名? 不,不要依赖编译器为您选择正确的选项。如果您不喜欢手动输入所有选项,请使用 CMAKE 或 IDE(例如 VS code、Eclipse 或 XCode)为您构建系统
  • macOS 系统 clang++ 默认为 C++98。它相当现代,因为我相信完全支持 C++17。
  • 如果你在命令行输入g++ myprogram.cpp,那么你做错了什么。您将需要指定输出程序名称,并打开调试信息或优化级别,当然还有“-Wall”。将-std=c++11 标志与其他标志一起放入您的构建系统中,或者至少放入您的build.sh 中,然后重新开始编程。

标签: c++ c++11


【解决方案1】:

根据 cmets 中的讨论为这个问题提供正确的答案:

GCC 和 Clang 等编译器在其源代码中设置了默认值,并且无法通过修改配置文件等方式进行更改。更改默认值的唯一方法是在源代码中更改它并自己编译编译器。这不值得。

此外,编译器会不时更改其默认语言,并设置另一个默认值,例如到 C++11,将使所有非 C++11 代码都需要显式设置语言版本。

这是关键点:代码和编译选项是一体的。不要依赖编译器默认值。任何严肃的项目都会使用指定如何编译项目的构建系统(例如 Make)。

编辑

为了完整起见,GCC 10.2.0 的默认 C++ 版本在 /gcc/c-family/c-opts.c 中硬编码:

/* Set C++ standard to C++17 if not specified on the command line.  */
if (c_dialect_cxx ())
  set_std_cxx17 (/*ISO*/false);

【讨论】:

  • 这没有帮助,因为如果您已经拥有编译器,您可以更改编译器标准版本。更改源代码是解决此问题的一种非常迂回的方法,并且代码现在将不符合要求,因此可能无法在任何其他编译器上运行。如果您将自己绑定到特定编译器,则可以添加编译器标志以支持 C++11,只要您使用足够现代的编译器版本(ABI 在 GCC 4.7 之后中断,即第一个支持 C++11)。
  • 或者,tl;dr:如果您已经在使用支持 C++11 的特定编译器和版本,只需传递标志。您的代码不会在任何不支持 C++11 的编译器上编译。简而言之,这不仅仅是“不值得”,而是一个糟糕的主意。
  • @AlexanderHuszagh 我不确定我是否理解你的观点。 lostinparadise 询问如何将编译器的默认语言/版本更改为 C++11,这样他们就不必传递标志或使用别名(或构建系统)。我的回答是,这只能通过修改例如 GCC 的源代码来完成。我不是说这是个好主意——恰恰相反。
  • 他们特别问“有没有办法总是用 C++11 编译而不必使用 -std=c++11 和不使用别名?”,并提到了多个编译器。修改源代码仅适用于1 编译器,并且仅适用于如果编译器已经支持C++11。简而言之,除非您向后移植功能,否则修改源代码是无关紧要的:唯一的答案是您不能
  • 正确的答案是说你不能,然后强调如何在各种构建工具(例如 CMake 或 Meson)中做到这一点。
猜你喜欢
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 2015-11-03
  • 2013-01-04
相关资源
最近更新 更多