获取从无符号到有符号的隐式转换溢出警告
Getting warnings for implicit conversion overflow from unsigned to signed
考虑以下有问题的代码:
#include <iostream>
void foo(int64_t y) {
std::cout << y << "\n";
}
int main() {
uint64_t x = 14400000000000000000ull;
foo(x);
}
通常打印 -4046744073709551616
.
如何让编译器帮助解决此类 conversion/overflow 问题?我尝试了以下方法:
g++ -g overflow.cpp -fsanitize=undefined -Wall -Wextra -pedantic -Wconversion -Wconversion
clang++ -g overflow.cpp -fsanitize=undefined,integer,implicit-conversion -Wall -Wextra -pedantic
None 其中给出任何编译时或 运行 时警告。
(clang 版本 7.0.0, gcc 版本 8.2.1)
GCC 和 Clang 都有警告选项 -Wsign-conversion 以在这种情况下发出警告。
warning: implicit conversion changes signedness: 'uint64_t' (aka 'unsigned long') to 'int64_t' (aka 'long') [-Wsign-conversion]
注意 GCC 关于 -Wconversion 的文档
... Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.
另请注意,该程序格式正确(因此必须成功编译)并且没有未定义的行为(因此没有理由触发消毒程序)。将不可表示的数字转换为有符号的结果在实现定义的值中。
这里的问题是 -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
这将警告您符号不匹配。
考虑以下有问题的代码:
#include <iostream>
void foo(int64_t y) {
std::cout << y << "\n";
}
int main() {
uint64_t x = 14400000000000000000ull;
foo(x);
}
通常打印 -4046744073709551616
.
如何让编译器帮助解决此类 conversion/overflow 问题?我尝试了以下方法:
g++ -g overflow.cpp -fsanitize=undefined -Wall -Wextra -pedantic -Wconversion -Wconversion
clang++ -g overflow.cpp -fsanitize=undefined,integer,implicit-conversion -Wall -Wextra -pedantic
None 其中给出任何编译时或 运行 时警告。
(clang 版本 7.0.0, gcc 版本 8.2.1)
GCC 和 Clang 都有警告选项 -Wsign-conversion 以在这种情况下发出警告。
warning: implicit conversion changes signedness: 'uint64_t' (aka 'unsigned long') to 'int64_t' (aka 'long') [-Wsign-conversion]
注意 GCC 关于 -Wconversion 的文档
... Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.
另请注意,该程序格式正确(因此必须成功编译)并且没有未定义的行为(因此没有理由触发消毒程序)。将不可表示的数字转换为有符号的结果在实现定义的值中。
这里的问题是 -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
这将警告您符号不匹配。