正如Clang似乎指出的那样,这段代码是否真的未定义?

Tob*_*ias 12 c++ clang sanitizer libstdc++ undefined-behavior

我打开了-fsanitize=undefined使用Catch(单元测试库)的项目.来自Catch的一行被发信号通知此标志导致未定义的行为.我设法做了一个孤立的例子:

#include <iomanip>
#include <sstream>

int main()
{
    std::ostringstream os; 
    os << "0x" << std::setfill('0') << std::hex;
}
Run Code Online (Sandbox Code Playgroud)

编译:

clang++ -fsanitize=undefined main.cpp
Run Code Online (Sandbox Code Playgroud)

如果我运行它,将给出以下打印:

/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/ios_base.h:96:24: runtime error: load of value 4294967221, which is not a valid value for type 'std::_Ios_Fmtflags'
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/ios_base.h:76:67: runtime error: load of value 4294967221, which is not a valid value for type 'std::_Ios_Fmtflags'
Run Code Online (Sandbox Code Playgroud)

这对我来说是clang 3.6.0和一个有clang的朋友3.4-1ubuntu3.在gcc版本上我不会发生这种情况4.9.2

那么这里有什么?这段代码真的很糟糕,还是clang的结尾有什么可疑的?

Sha*_*our 12

这是libstdc ++中的一个错误,来自cfe-dev邮件列表线程,标题为-fsanitize = undefined,共享库 说:

这是libstdc ++中的一个错误.你可以使用一个清洁剂黑名单文件解决它,一旦Will的修补程序落地,但是现在,手动过滤它们可能是你最好的选择.

这是修补它的补丁; 我将在接下来的几天内将其推向libstdc ++上游.[...]

正如我指出的情况并不少见,看看系统中的意见DYP clang使用libstdc++,而不是libc++如果我们测试这在Coliru明确使用的libstdc ++通过-stdlib=libstdc++我们的确可以重现该问题.

以下libstdc++错误报告:ios_base.h中运算符〜计算的错误枚举值涵盖了此问题,并说:

为ios_base.h中的枚举定义的重载运算符具有以下形式:

Enum operator~(Enum e) { return Enum(~static_cast<int>(e)); }
Run Code Online (Sandbox Code Playgroud)

〜创建枚举类型值范围之外的值,因此返回Enum类型的转换具有未指定的值(请参阅[expr.static.cast] p10),并且实际上它会生成超出范围的Enum值Enum类型的可表示值,因此行为未定义.

供参考[expr.static.cast] p10说:

可以将整数或枚举类型的值显式转换为枚举类型.如果原始值在枚举值(7.2)的范围内,则该值不变.否则,结果值未指定(可能不在该范围内).浮点类型的值也可以转换为枚举类型.结果值与将原始值转换为枚举的基础类型(4.9)以及随后的枚举类型相同.

正如hvd所说这是正式未指明的行为,但理查德指出,在实践中最终会成为未定义的行为.

TC指出DR 1766将其从未指定行为更改为未定义行为:超出枚举值范围的值:

虽然问题1094澄清了枚举类型的表达式的值可能不在转换为枚举类型后的枚举值的范围内(见5.2.9 [expr.static.cast]第10段),结果只是一个未指明的值.鉴于未定义的行为使表达式非常量,这应该可以加强以产生未定义的行为.另见9.6 [class.bit]第4段.

新措辞出现在N4431的标准草案中.

  • @hvd [CWG 1766](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1766)完全没有对此进行定义. (2认同)