Exceptions en virgule flottante – bug gcc?

Considérons le code suivant:

#include  #include  int main() { #pragma STDC FENV_ACCESS ON 1.0/0.0; printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); } 

Je m’attendrais à ce qu’il imprime une valeur non nulle correspondant à FE_DIVBYZERO , mais il affiche 0. Changer la deuxième ligne de main en double x = 1.0/0.0; donne le comportement attendu. Est-ce autorisé ou s’agit-il d’un bug?

Edit: Pour ce que cela vaut, au début, il peut sembler que, dans la plupart des codes du monde réel, les opérations qui pourraient causer le déclenchement des exceptions fenv ne puissent pas être optimisées. débordement, div par zéro, etc. Cependant, les choses se compliquent et un réel problème se pose lorsque vous envisagez l’inline et l’optimisation. Si une telle fonction était intégrée dans une situation où elle finirait toujours par se diviser par zéro à cause d’arguments constants, gcc pourrait devenir vraiment intelligent et optimiser l’ensemble de la fonction intégrée essentiellement pour return INFINITY; sans soulever aucune exception.

C’est le comportement attendu. gcc n’évalue pas l’expression, car elle n’aurait rien à voir par la suite.

Si vous comstackz avec “-Wall”, il vous avertit que la déclaration n’a aucun effet et qu’elle ignore la déclaration pragma.

GCC n’est pas entièrement conforme à C99. Pour plus d’informations, voir: http://gcc.gnu.org/c99status.html

Pour savoir comment implémenter ce comportement, voir: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785

C’est un peu une zone grise. Une lecture ssortingcte de la section de la norme relative à l’environnement en virgule flottante pourrait facilement faire croire qu’il s’agit d’un bogue. Je suppose que les responsables de GCC seront en désaccord avec cette lecture, cependant.

D’ailleurs, je ne suis pas sûr que GCC prétend même comprendre le pragma FENV_ACCESS. Certainement pas les versions précédentes.

Comstackr avec -Wall sur gcc 4.6.0 dit:

 fc:5:0: warning: ignoring #pragma FENV_ACCESS ON [-Wunknown-pragmas] 

Selon les pages d’information du CCG :

 * `The default state for the `FENV_ACCESS' pragma (C99 7.6.1).' This pragma is not implemented, but the default is to "off" unless `-frounding-math' is used in which case it is "on". 

Malheureusement, -frounding-math ne semble pas avoir d’effet sur votre programme.

On peut soutenir qu’un bogue du compilateur; Je demanderais sur l’une des listes de diffusion de GCC.

Il est possible que votre compilateur ait optimisé la version d’origine. Reconnaissant que les deux constantes ne sont pas “utilisées” dans un sens non sortingvial, il se peut même qu’elles n’existent pas dans le binary compilé.

Le deuxième exemple modifie cela en affectant réellement l’opération à une variable.

Je pense que l’expression est optimisée dans le premier cas, mais pas dans le second. Je peux reproduire vos résultats avec gcc 4.2 avec gcc -O0 , mais si je passe à gcc -O3 j’obtiens 0 dans les deux cas.