constexpr int i = 100;
struct F { F(unsigned int){} };
int main() { F{i}; }
上面的代码段:
使用g++ 7
在-Wall -Wextra -Wpedantic
上编译,但没有任何警告。
使用clang++ 4
在-Wall -Wextra -Wpedantic
上编译,但没有任何警告。
无法在MSVC 2017
上编译:
从'const int'转换为'unsigned int'需要缩小转换
问:这里的MSVC错了吗?
int i = 100;
struct F { F(unsigned int){} };
int main() { F{i}; }
使用g++ 7
在-Wall -Wextra -Wpedantic
上编译带有警告的 :
缩小'i'从'int'到'unsigned int'的转换
无法使用clang++ 4
编译-Wall -Wextra -Wpedantic
:
在初始化列表中,非常量表达式不能从“int”类型缩小为“unsigned int”
无法在MSVC 2017
上编译:
从'const int'转换为'unsigned int'需要缩小转换
问:这里的g ++错了吗? (即它应该产生硬错误吗?)
答案 0 :(得分:4)
永远不要求任何C ++程序产生硬错误。有打印诊断的要求。诊断的形式没有通过标准规定:一个古老的笑话是打印出单个空间满足标准的诊断要求。这将是一个实施质量问题。
标准不完整的程序标准对其行为没有任何限制,有时也是强制性诊断。
有些程序格式错误且需要诊断。处理它的一种方法是产生一条消息,说明它是一个错误,然后不生成任何二进制文件来运行。另一种方法是生成一条消息,说明它是一个警告,然后生成一个可以运行的二进制文件。
因此,g ++在标准下仅仅打印出警告并没有错。
结果程序在技术上是所有未定义的行为; g ++可以在运行时格式化您的硬盘而不违反标准。这将被视为实施质量问题。
Shafik's answer here涵盖了第一个问题。 i
是常量表达式,其值适合目标类型;关于缩小转换应该没有警告或错误。
C ++标准并不能保护您免受恶意编译器的攻击。</ p>
据报道,-pedantic-errors
可以传递给g ++,以便在标准规定生成的程序格式错误时生成硬错误而不是警告。