获取隐式转换溢出从无符号到已签名的警告



考虑以下有问题的代码:

#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(

这里的问题是,如果值在强制转换为源类型时可能不是同一类型,-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

这将警告您标志不匹配。

GCC和Clang都有警告选项-Wsign-convert,在这种情况下发出警告。

警告:隐式转换将符号:"uint64_t"(又名"无符号长整型"(更改为"int64_t"(又名"长"([-Wsign-conversion]

注意 GCC 关于 -Wconversion 的文档

。默认情况下,有关有符号整数和无符号整数之间转换的警告在 C++ 中处于禁用状态,除非显式启用了 -Wsign 转换。

另请注意,程序格式良好(因此必须成功编译(,并且没有未定义的行为(因此没有理由触发清理器(。将无法表示的数字转换为有符号的结果在实现定义的值中。

相关内容

最新更新