C++17使用designated initializers的合法性及规避-Wpedantic报错方法
问题1:未开启-Wpedantic时无警告的原因及是否属于未定义行为
- 无警告的原因:GCC很早就将designated initializers作为GNU扩展支持,默认编译模式下(未开启
-Wpedantic),编译器不会对广泛使用的自研非标准扩展主动触发警告,仅会在开启-Wpedantic时严格校验所选C++标准的语法要求,对不符合标准的用法输出诊断。 - 不属于未定义行为:C17标准本身不支持designated initializers语法,纯标准语境下属于语法错误,但GCC的C17模式对该语法的扩展实现是明确定义的,要求初始化顺序和结构体成员声明顺序完全一致、不允许跳过成员,和C++20的标准规则完全兼容,只要编译用的是GCC,运行行为是完全确定的。
问题2:保留-Wpedantic的同时规避报错的方案
有两种可行方案,无需重新编译GCC:
方案1:全局单独关闭对应警告(推荐)
GCC为该类语法专门提供了独立的警告开关-Wc++20-designator,你只需要在编译参数中追加-Wno-c++20-designator即可单独抑制该特定报错,不会影响其他-Wpedantic校验规则的生效。
示例编译指令:
g++ -std=c++17 -Wpedantic -Werror -Wno-c++20-designator your_code.cpp
方案2:代码段局部抑制警告
如果不想全局关闭该校验,只允许特定代码段使用该语法,可以在对应代码前后添加GCC诊断预处理指令,局部临时关闭-Wpedantic检查:
#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" // 仅该区间内的designated initializers不会触发报错 struct Foo { int a; float b; }; Foo f { .a = 7, .b = 42.1f, }; #pragma GCC diagnostic pop
这种方案的好处是其他代码的-Wpedantic校验完全不受影响,只有你明确标记的代码段可以用该语法,合规性更高。
内容的提问来源于stack exchange,提问作者davidA
相关产品推荐
相关产品推荐

