考虑以下有问题的代码:
#include <iostream>
void foo(int64_t y) {
std::cout << y << "\n";
}
int main() {
uint64_t x = 14400000000000000000ull;
foo(x);
}通常打印-4046744073709551616。
如何让编译器帮助解决这种类型的转换/溢出问题?我尝试了以下几点:
g++ -g overflow.cpp -fsanitize=undefined -Wall -Wextra -pedantic -Wconversion -Wconversion
clang++ -g overflow.cpp -fsanitize=undefined,integer,implicit-conversion -Wall -Wextra -pedantic它们都没有给出任何编译或运行时警告。
(clang版本7.0.0,gcc版本8.2.1)
发布于 2018-10-22 15:22:34
这里的问题是,-Wconversion只会警告当转换回源类型时,该值可能不是相同的类型。例如,如果foo采用int,那么-Wconversion将发出警告,因为您可能无法将int中的值转换回原始的uint64_t值。如果我们有
uint64_t u = some_value;
int64_t s = static_cast<int64_t>(u);
uint64_t check = static_cast<uint64_t>(s)那么check == u将永远是真的(只要int64_t也是两种恭维),所以-Wconversion不会发出警告,因为我们会得到源值。
在这种情况下你需要的是
-Wsign-conversion这会警告你这些迹象不匹配。
发布于 2018-10-22 15:20:47
GCC和Clang都有警告选项--W符号转换--在这种情况下可以发出警告。
警告:隐式转换更改签名性:“uint64_t”(又名“无符号长”)改为“int64_t”(又名“长”)-W符号-转换
注GCC关于-Wconversion的文献
..。关于有符号整数和无符号整数之间转换的警告默认情况下在C++中禁用,除非显式启用-W符号-转换。
还请注意,程序是格式良好的(因此必须成功编译),并且没有未定义的行为(因此没有理由触发杀菌剂)。在实现定义值中将不可表示的数字转换为已签名的结果。
https://stackoverflow.com/questions/52932370
复制相似问题