如果我编译这段代码
#include <bitset>
int
main(int argc, char** argv) {
std::bitset<96> mask;
mask.set();
return 0;
}
与
clang++ -fsanitize=integer test_bitset.cpp
运行结果,我得到
.../include/c++/12/bitset:657:46: runtime error: left shift of 18446744073709551615 by 32 places cannot be represented in type 'std::_Sanitize::_WordT' (aka 'unsigned long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior .../include/c++/12/bitset:657:46 in
这看起来有点像为什么 clang sanitizer 认为无符号数的左移是未定义的? 但如果我尝试使用
禁用检查clang++ -fsanitize=integer -fno-sanitize=unsigned-integer-overflow test_bitset.cpp
未定义的行为仍然存在。为了增加混乱,如果我手动启用“所有”整数检查(如文档中所述)
clang++ -fsanitize=signed-integer-overflow,unsigned-integer-overflow,shift,integer-divide-by-zero,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change test_bitset.cpp
未定义的行为消失了。那么显然
-fsanitize=integer
的作用还不止于此?
我可以使用位集上的黑名单来消除错误,但我真的想知道它是否是 stdlib 中的错误或可以安全地忽略。
我在标准 ubuntu 22.04 上用 clang 14 和 clang 15 尝试了这个。任何提示表示赞赏。
正如 @user17732522 正确指出的那样,这只是 clang 文档中的一个错误。避免检查的正确调用是
clang++ -fsanitize=integer -fno-sanitize=unsigned-shift-base test_bitset.cpp
,而检查只是过于敏感,它不是是未定义的行为。