C++ 类型索引散列导致未定义的行为
C++ type index hashing causes undefined behaviour
按照 https://en.cppreference.com/w/cpp/types/type_index 上的示例并使用 -fsanitize=address,integer,undefined
进行编译揭示了未定义的行为。代码是:
struct A
{
virtual ~A()
{}
};
struct B : A
{
};
struct C : A
{
};
int main() {
std::unordered_map<std::type_index, std::string> type_names;
std::cout << "A" << std::endl;
type_names[std::type_index(typeid(int))] = "int";
std::cout << "B" << std::endl;
type_names[std::type_index(typeid(double))] = "double";
std::cout << "C" << std::endl;
type_names[std::type_index(typeid(A))] = "A";
std::cout << "D" << std::endl;
type_names[std::type_index(typeid(B))] = "B";
std::cout << "E" << std::endl;
type_names[std::type_index(typeid(C))] = "C";
std::cout << "F" << std::endl;
return 0;
}
编译后 运行 产生:
A
B
C
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/typeinfo:192:26: runtime error: unsigned integer overflow: 8244747390267580164 * 33 cannot be represented in type 'unsigned long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/typeinfo:192:26 in
D
E
F
正如所见,clang 抱怨用户定义类型的未定义行为。有人知道不会导致未定义行为的正确实现是什么样的吗?
无符号整数溢出不是未定义的行为,但是 UBSan 仍然可以选择检查它,因为它通常仍然是一个错误。但在这种情况下不是。这个警告是由一个完全无辜的哈希函数引起的。它应该有无符号整数溢出。
你可以silence这个警告。
您也可以向 libc++ 维护者报告错误。他们可能应该添加
__attribute__((no_sanitize("integer")))
或一些类似的违规功能。
按照 https://en.cppreference.com/w/cpp/types/type_index 上的示例并使用 -fsanitize=address,integer,undefined
进行编译揭示了未定义的行为。代码是:
struct A
{
virtual ~A()
{}
};
struct B : A
{
};
struct C : A
{
};
int main() {
std::unordered_map<std::type_index, std::string> type_names;
std::cout << "A" << std::endl;
type_names[std::type_index(typeid(int))] = "int";
std::cout << "B" << std::endl;
type_names[std::type_index(typeid(double))] = "double";
std::cout << "C" << std::endl;
type_names[std::type_index(typeid(A))] = "A";
std::cout << "D" << std::endl;
type_names[std::type_index(typeid(B))] = "B";
std::cout << "E" << std::endl;
type_names[std::type_index(typeid(C))] = "C";
std::cout << "F" << std::endl;
return 0;
}
编译后 运行 产生:
A
B
C
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/typeinfo:192:26: runtime error: unsigned integer overflow: 8244747390267580164 * 33 cannot be represented in type 'unsigned long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/typeinfo:192:26 in
D
E
F
正如所见,clang 抱怨用户定义类型的未定义行为。有人知道不会导致未定义行为的正确实现是什么样的吗?
无符号整数溢出不是未定义的行为,但是 UBSan 仍然可以选择检查它,因为它通常仍然是一个错误。但在这种情况下不是。这个警告是由一个完全无辜的哈希函数引起的。它应该有无符号整数溢出。
你可以silence这个警告。
您也可以向 libc++ 维护者报告错误。他们可能应该添加
__attribute__((no_sanitize("integer")))
或一些类似的违规功能。