9

考虑以下 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 具有预期值,但浮点 a 变为等于 -1反而。

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

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

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

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

4

2 回答 2

6

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

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

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

于 2013-07-12T10:45:08.770 回答
5

您描述的是编译器错误。

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

unsigned long x = 1;
float a = -x;
double b = -x;
于 2013-07-12T10:03:07.873 回答