提问人:Raz Cohen 提问时间:6/22/2023 最后编辑:Raz Cohen 更新时间:6/22/2023 访问量:90
UBA 清理器在 C++ 上将负双重命名为无符号长长的问题
Issue with UBA sanitizer casting negative double to unsigned long long on C++
问:
我一直在使用 C++,并一直在使用 UBA 清理器将双精度转换为无符号长整长。但是,当值为负数时,我遇到了一个问题,这会导致错误消息:“运行时错误:值 -2 超出了类型为'long long unsigned int'的可表示值范围”
代码是这样的:
unsigned long long valueULL = 0;
double value = -2;
valueULL = (unsigned long long)value;
我试图改用这个演员表,但它没有帮助:
valueULL = std::make_unsigned_t<unsigned long long>(value);
有没有办法在不遇到此错误的情况下强制转换它?
答:
1赞
Jan Schultke
6/22/2023
#1
看来你指的是 clang 的 UBSanitizer。
在这种情况下,清理程序是正确的,并且您的代码确实包含未定义的行为:-fsanitize=undefined
浮点类型的 prvalue 可以转换为整数类型的 prvalue。 转换被截断;也就是说,小数部分被丢弃。如果截断的值无法在目标类型中表示,则行为未定义。
您可以通过两步强制转换来修复未定义的行为:
double value = -2;
auto valueULL = static_cast<unsigned long long>(static_cast<long long>(value));
或者,您可以调用 std::llround:
auto valueULL = static_cast<unsigned long long>(std::llround(value));
注意:这将产生一个非常大的值,即 .如果这是您真正想要的,那么这些解决方案是有意义的。
否则,您应该听消毒剂的意见,并确保在转换为类型之前不会变成负数。ULLONG_MAX - 2
double
unsigned
评论
value
double
2.0
double
-2.0
unsigned
-2.0
(unsigned long long)(long long)value