constexpr构造函数在GCC编译通过但Clang报错的问题咨询
GCC对C++14 constexpr构造函数的非标准行为分析
我最近在测试C++14及更高版本的constexpr构造函数时,碰到了一个违背预期的情况,跟大家聊聊:
测试过程与现象
我编写了一个带有constexpr构造函数的类,构造函数中直接包含了std::cout的流输出操作。按照C++14的标准,constexpr函数的函数体只能包含有限的、无副作用的编译期合法操作,IO操作显然不在此列,所以我原本以为用命令:
g++ -std=c++14 -o cx_test cx_test.cpp
编译时会直接触发错误。但实际情况是:
- GCC编译完全通过,运行生成的程序时,还能正常输出构造函数里的cout内容;
- 换用Clang编译时,立刻抛出编译错误,明确指出
constexpr函数中不允许使用IO操作,这完全符合我的预期。
为什么说这是GCC的bug?
C++14标准对constexpr函数的函数体有严格限制,只能包含以下内容:
- 空语句(
;) static_assert声明- typedef、别名声明(
using别名) - using声明/指令
- 不含
try块的复合语句 - 返回语句
- 仅由constexpr合法表达式组成的表达式语句
std::cout的输出操作属于带有运行时副作用的操作,根本无法在编译期执行,完全不符合constexpr函数的要求。GCC在这里没有正确执行编译期检查,允许了非法代码通过编译,这明显是违反C++14标准的行为。
你可以做个进一步验证:如果把这个构造函数用于编译期上下文(比如初始化一个constexpr对象,或者作为模板参数的一部分),GCC会立刻报错——因为它没法在编译期完成IO操作,但它在普通编译场景下放过了这个错误,这确实是标准符合性上的问题。
内容的提问来源于stack exchange,提问作者callyalater
相关产品推荐
相关产品推荐

