从无符号除法结果赋值时的符号转换警告
Warnings on sign conversion when assigning from the result of unsigned division
我用 -Wsign-conversion
编译了以下代码:
int main()
{
unsigned int a = 8;
int b = a + 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int c = a - 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int d = a * 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int e = a / 8u; // gcc warns, but no warning in clang
}
从无符号除法的结果赋值时,Clang 不会发出警告,但 gcc 会。
为什么在这个特殊情况下会有所不同?
Clang 只是有点聪明:无符号整数除以大于或等于 2 的无符号整数意味着无符号整数结果将始终适合有符号整数对应项(对应于除法表达式)。但是,如果您除以一个值为 1 的无符号整数,则结果不再保证适合对应的有符号整数,并且 Clang 确实 发出警告:
#include <cstdint>
int main() {
uint8_t a = 240; // '240 / 1' will not fit in int8_t
int8_t e = a / 2u; // No warning in clang
int8_t f = a / 1u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int8_t' (aka 'signed char') [-Wsign-conversion]
}
也有人认为 Clang 应该能够忽略乘以 0 的类似特殊情况的警告;但是 Clang 不会,而 GCC 会:
// Clang warns, no warning in GCC.
int8_t g = a * 0u;
在这种情况下,Clang 非常聪明,w.r.t。部门和 GCC w.r.t。乘法。
最后,请注意,Clang 在除法期间发出此警告的门控似乎仅在除以 1 时出现,因为如果除以 0u
,您将不会得到相同的 -Wsign-conversion
;可以说它已被更相关的(在这种情况下)覆盖 -Wdivision-by-zero
警告:
int8_t h = a / 0u;
warning: division by zero is undefined [-Wdivision-by-zero]
我用 -Wsign-conversion
编译了以下代码:
int main()
{
unsigned int a = 8;
int b = a + 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int c = a - 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int d = a * 8u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int'
int e = a / 8u; // gcc warns, but no warning in clang
}
从无符号除法的结果赋值时,Clang 不会发出警告,但 gcc 会。
为什么在这个特殊情况下会有所不同?
Clang 只是有点聪明:无符号整数除以大于或等于 2 的无符号整数意味着无符号整数结果将始终适合有符号整数对应项(对应于除法表达式)。但是,如果您除以一个值为 1 的无符号整数,则结果不再保证适合对应的有符号整数,并且 Clang 确实 发出警告:
#include <cstdint>
int main() {
uint8_t a = 240; // '240 / 1' will not fit in int8_t
int8_t e = a / 2u; // No warning in clang
int8_t f = a / 1u; // warning: implicit conversion changes signedness: 'unsigned int' to 'int8_t' (aka 'signed char') [-Wsign-conversion]
}
也有人认为 Clang 应该能够忽略乘以 0 的类似特殊情况的警告;但是 Clang 不会,而 GCC 会:
// Clang warns, no warning in GCC.
int8_t g = a * 0u;
在这种情况下,Clang 非常聪明,w.r.t。部门和 GCC w.r.t。乘法。
最后,请注意,Clang 在除法期间发出此警告的门控似乎仅在除以 1 时出现,因为如果除以 0u
,您将不会得到相同的 -Wsign-conversion
;可以说它已被更相关的(在这种情况下)覆盖 -Wdivision-by-zero
警告:
int8_t h = a / 0u;
warning: division by zero is undefined [-Wdivision-by-zero]