Poniższy program (zaadaptowany z here) daje niespójne wyniki w kompilacji z GCC (4.8.2) i Clangiem (3.5.1). W szczególności wynik GCC nie zmienia się, nawet gdy ma on wartość FLT_EVAL_METHOD
.To samo FLT_EVAL_METHOD, różne wyniki w GCC/Clang
#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);
}
Testy:
$ 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
Należy zauważyć, że zgodnie z this blog post GCC 4.4.3 stosowane do wyjścia 0 zamiast 1 w drugim badaniu.
A possibly related question wskazuje, że błąd został poprawiony w GCC 4.6, co może wyjaśniać, dlaczego wynik GCC jest inny.
Chciałbym potwierdzić, czy którykolwiek z tych wyników byłby niepoprawny, lub gdyby niektóre subtelne kroki oceny (np. Nowa optymalizacja preprocesora) uzasadniałyby różnicę między tymi kompilatorami.
Musiałem ostatnio zbadać zachowanie starych wersji GCC i ktoś wskazał mi na https://gcc.godbolt.org, który był bardzo przydatny. Nie ma GCC 4.4.3, ale ma 4.4.7. –