c++ - gcc 选项 std=gnu++17 与 std=c++17
问题描述
我在使用 g++(我尝试了版本 8 到 11)时遇到了编译错误,-std=gnu++17
但可以使用选项编译相同的代码-std=c++17
。
#include <complex.h>
int main()
{
int I=0;
return I;
}
使用 option -std=gnu++17
,这会导致以下错误:
error: invalid cast from type '__complex__ float' to type 'int'
5 | int I=0;
使用该选项-std=c++17
,它编译时不会出现警告和错误。
我知道在complex.h
标题中有一个宏定义#define I _Complex_I
。gcc 文档说该选项-std=gnu++17
添加了相应 c++ 标准的 GNU 方言。尽管如此,我还是不明白为什么这会导致上述程序的编译有所不同。
背景:当我开始使用 cmake 功能时遇到了这种行为,该功能cxx_std_17
添加了标志std=gnu++17
并导致各种编译错误,因为一个第三方库使用标识符I
而另一个包含 header complex.h
。
解决方案
C++ 标准说:(C++17 C.6.1/3):
C++ 头文件
<ccomplex>
(D.4.1) 和<ctgmath>
(D.4.4) 以及它们相应的 C 头文件<complex.h>
和<tgmath.h>
不包含来自 C 标准库的任何内容,而仅包含来自 C++ 标准库的其他头文件。
因此 C 的 complex.h 不包含在 C++ 中,这意味着您的代码中I
不应定义任何内容。
当允许 GNU 扩展时,GCC 确实包含 C 内容作为扩展。参见PR 82417:
作为扩展,<complex.h> 的 C++ 版本包括 C 版本,但它定义了具有不应在 ISO C++ 中定义的非保留名称的宏。仅包含用于非严格模式或 C++11 之前的 C 标头(因为 C++98 根本没有提及 <complex.h>)。
推荐阅读
- android - 没有带有cordova> = 7的AndroidManifest.xml文件
- php - 将 Cassandra UUID 对象转换为 PHP 字符串
- java - 如何创建具有 n 深度的 Freemarker 模板?
- python - 在逗号分隔值的熊猫中拆分列但保持顺序
- python - 每行 Numpy 动态切片
- sql - 如何在 PL/SQL Oracle 中获取每年日期范围的数字总和
- hibernate - Hibernate DB2 方言分页问题
- angularjs - 在 Visual Studio 中运行 AngularJS 应用程序
- three.js - Three.js 指针锁定控件在天穹上创建洞
- jquery - 我可以通过其他 jQuery 方法修改用作 insertAfter 参数的选择器吗?