为何Clang对符合C++标准的constexpr结构体成员常量表达式告警?
问题:Clang对
S.i作为switch的case分支常量发出告警的原因 根据你提到的N3220(C11标准草案)「6.6 常量表达式」章节,你认为以下代码中的S.i属于整数常量表达式:
constexpr struct { int i; } S = {.i = 100};
但在switch语句的case分支中使用S.i时,Clang会触发如下告警:
int main(void) { int i = get_i(); switch(i) { case S.i: break; // warning: expression is not an integer constant expression; folding it to a constant is a GNU extension [-Wgnu-folding-constant] } }
告警产生的核心原因如下:
- 混淆了C与C++的标准规则:你查阅的N3220是C语言的C11标准草案,而你的代码使用了C专属的
constexpr关键字,属于C代码,两者的常量表达式规则并不通用。 - C++标准对case标签的严格限制:在C标准中,switch的case标签要求使用整数类型的常量表达式,但非静态类成员的访问(哪怕是constexpr全局对象的成员),在C11/14的标准规则里,并不被允许作为case标签的合法常量表达式。Clang严格遵循C++标准,因此判定
S.i不符合要求。 - GNU扩展的兼容性提示:Clang支持GNU编译器的扩展特性,其中包括将这类明显是常量的表达式折叠为具体数值,但这并非标准C++的规定。告警的目的是提醒你:当前代码依赖了非标准的GNU扩展,在不支持该扩展的编译器上可能无法编译通过。
内容的提问来源于stack exchange,提问作者Evgeny Ilyin
相关产品推荐
相关产品推荐

