【发布时间】:2015-03-04 09:55:14
【问题描述】:
以下程序(改编自 here)在使用 GCC (4.8.2) 和 Clang (3.5.1) 编译时给出不一致的结果。特别是,即使FLT_EVAL_METHOD 改变,GCC 结果也不会改变。
#include <stdio.h>
#include <float.h>
int r1;
double ten = 10.0;
int main(int c, char **v) {
printf("FLT_EVAL_METHOD = %d\n", FLT_EVAL_METHOD);
r1 = 0.1 == (1.0 / ten);
printf("0.1 = %a, 1.0/ten = %a\n", 0.1, 1.0 / ten);
printf("r1=%d\n", r1);
}
测试:
$ gcc -std=c99 t.c && ./a.out
FLT_EVAL_METHOD = 0
0.1 = 0x1.999999999999ap-4, 1.0/ten = 0x1.999999999999ap-4
r1=1
$ gcc -std=c99 -mpfmath=387 t.c && ./a.out
FLT_EVAL_METHOD = 2
0.1 = 0x0.0000000000001p-1022, 1.0/ten = 0x0p+0
r1=1
$ clang -std=c99 t.c && ./a.out
FLT_EVAL_METHOD = 0
0.1 = 0x1.999999999999ap-4, 1.0/ten = 0x1.999999999999ap-4
r1=1
$ clang -std=c99 -mfpmath=387 -mno-sse t.c && ./a.out
FLT_EVAL_METHOD = 2
0.1 = 0x0.07fff00000001p-1022, 1.0/ten = 0x0p+0
r1=0
请注意,根据this blog post,GCC 4.4.3 过去在第二次测试中输出 0 而不是 1。
possibly related question 表示在 GCC 4.6 中已更正了一个错误,这可能解释了为什么 GCC 的结果不同。
我想确认这些结果中是否有任何不正确,或者是否有一些微妙的评估步骤(例如新的预处理器优化)可以证明这些编译器之间的差异是合理的。
【问题讨论】:
-
我最近不得不调查旧 GCC 版本的行为,有人指点我 gcc.godbolt.org,这非常有用。它没有 GCC 4.4.3,但它有 4.4.7。
-
gcc -std=c99 -mpfmath=387 t.c && ./a.out真的是gcc -std=c99 -mfpmath=387 t.c && ./a.out(错字?)
标签: c gcc floating-point clang