一元减号和浮点数转换的组合

考虑以下C语句:

unsigned long x = 1; float a = -x; double b = -x; 

我希望一元减项产生一个等于ULONG_MAX的无符号长值,a和b分别设置为ULONG_MAX的单精度和双精度表示。

这是我在32位Linux上使用gcc 4.4.7以及在64位Linux上使用Intel和PGI编译器获得的结果。 但是,对于64位Linux上的gcc(测试版本4.4.7,4.7.2和4.8.0,都带有-O0和-O2),双变量b具有预期值,但float a等于-1代替。

相比之下,以下语句将在我测试的所有编译器和系统上将a和b设置为ULONG_MAX的浮点表示:

 unsigned long x = 1; unsigned long y = -x; float a = y; double b = y; 

如果我使用unsigned int而不是unsigned long,我也会在所有系统上得到预期的结果。

这是某种未定义的行为还是编译器错误?

这是由于GCC中的一个错误 – 类型转换发生在否定之前。

这个问题似乎已经存在了一段时间。 错误55771 – 错误交换了否定和类型转换

在第二个示例中,否定发生在类型转换之前。 因此,您会看到预期的结果。

你描述的是编译器错误。

(以下程序中没有未定义的行为来原谅编译器)

 unsigned long x = 1; float a = -x; double b = -x;