J'ai extrait d'un programme le code minimal suivant :
-----------------------------------
#include <iostream>
class truc {
int Ni;
void print ();
int test (int i);
};
void truc::print () {
std::cout << test (Ni-2);
}
int truc::test (int i) {
return (i<Ni) ? 1 : 2;
}
-----------------------------------
Avec g++ version 4.4.1 :
g++ -c -O2 -Wall truc.cpp
truc.cpp: In member function ‘void truc::print()’:
truc.cpp:11: warning: assuming signed overflow does not occur when
assuming that (X - c) <= X is always true
Ici le test (i<Ni) est toujours vrai, ce qui semble déranger g++.
Il n'y a plus de warning sans le -O2, ou avec des unsigned int (mais
j'ai besoin de int dans le vrai prog).
Je ne me vois pas écrire une fonction test() spécialisée pour les cas où
le test est inutile, d'autant plus que ces cas ne sautent pas aux yeux
dans le vrai prog comme ici (constantes et macros réparties dans
plusieurs fichiers), ou alors autant jeter la machine et tout calculer à
la main si elle ne veut plus bosser pour nous.
Fais-je une ânerie que je ne vois pas, ou bien est-ce g++ ?
Ici le test (i<Ni) est toujours vrai, ce qui semble déranger g++.
Ca ne le derange pas. J'ai pas verifie exactement ce qu'il fait -- et encore moins cherche a le faire version par version -- mais voici ma comprehension des choses.
Le test "i < i - 2" (qui est en cause ici apres inlining) est un comportement indefini. Face a de tels comportements, il y a -- au moins -- deux ecoles.
Celle qui dit "le compilateur peut faire n'importe quoi et il faut en profiter pour optimiser le cas defini". Donc supprimer le test.
La deuxieme dit "C est un langage de base niveau, il faut faire ce qui est naturel pour la machine cible, c'est a dire que le test doit etre vrai en cas d'overflow; d'autant plus que c'est le comportement historique des compilateurs C. Le comportement est formellement indefini mais c'est pour permettre une implementation naturelle du C sur des machines exotiques, pas pour laisser faire n'importe quoi sous pretexte d'optimisations".
Par defaut, g++ se comporte suivant la premiere ecole, mais donne un warning. Il y a un flag (-fwrapv si j'ai bonne memoire) qui le fait se comporter suivant la deuxieme.
Ici le test (i<Ni) est toujours vrai, ce qui semble déranger g++.
Ca ne le derange pas. J'ai pas verifie exactement ce qu'il fait -- et
encore moins cherche a le faire version par version -- mais voici ma
comprehension des choses.
Le test "i < i - 2" (qui est en cause ici apres inlining) est un
comportement indefini. Face a de tels comportements, il y a -- au moins --
deux ecoles.
Celle qui dit "le compilateur peut faire n'importe quoi et il faut en
profiter pour optimiser le cas defini". Donc supprimer le test.
La deuxieme dit "C est un langage de base niveau, il faut faire ce qui est
naturel pour la machine cible, c'est a dire que le test doit etre vrai en
cas d'overflow; d'autant plus que c'est le comportement historique des
compilateurs C. Le comportement est formellement indefini mais c'est pour
permettre une implementation naturelle du C sur des machines exotiques, pas
pour laisser faire n'importe quoi sous pretexte d'optimisations".
Par defaut, g++ se comporte suivant la premiere ecole, mais donne un
warning. Il y a un flag (-fwrapv si j'ai bonne memoire) qui le fait se
comporter suivant la deuxieme.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Ici le test (i<Ni) est toujours vrai, ce qui semble déranger g++.
Ca ne le derange pas. J'ai pas verifie exactement ce qu'il fait -- et encore moins cherche a le faire version par version -- mais voici ma comprehension des choses.
Le test "i < i - 2" (qui est en cause ici apres inlining) est un comportement indefini. Face a de tels comportements, il y a -- au moins -- deux ecoles.
Celle qui dit "le compilateur peut faire n'importe quoi et il faut en profiter pour optimiser le cas defini". Donc supprimer le test.
La deuxieme dit "C est un langage de base niveau, il faut faire ce qui est naturel pour la machine cible, c'est a dire que le test doit etre vrai en cas d'overflow; d'autant plus que c'est le comportement historique des compilateurs C. Le comportement est formellement indefini mais c'est pour permettre une implementation naturelle du C sur des machines exotiques, pas pour laisser faire n'importe quoi sous pretexte d'optimisations".
Par defaut, g++ se comporte suivant la premiere ecole, mais donne un warning. Il y a un flag (-fwrapv si j'ai bonne memoire) qui le fait se comporter suivant la deuxieme.
> Ici le test (i<Ni) est toujours vrai, ce qui semble déranger g++.
Ca ne le derange pas. J'ai pas verifie exactement ce qu'il fait -- et encore moins cherche a le faire version par version -- mais voici ma comprehension des choses.
Le test "i < i - 2" (qui est en cause ici apres inlining) est un comportement indefini. Face a de tels comportements, il y a -- au moins -- deux ecoles.
Celle qui dit "le compilateur peut faire n'importe quoi et il faut en profiter pour optimiser le cas defini". Donc supprimer le test.
La deuxieme dit "C est un langage de base niveau, il faut faire ce qui est naturel pour la machine cible, c'est a dire que le test doit etre vrai en cas d'overflow; d'autant plus que c'est le comportement historique des compilateurs C. Le comportement est formellement indefini mais c'est pour permettre une implementation naturelle du C sur des machines exotiques, pas pour laisser faire n'importe quoi sous pretexte d'optimisations".
Par defaut, g++ se comporte suivant la premiere ecole, mais donne un warning. Il y a un flag (-fwrapv si j'ai bonne memoire) qui le fait se comporter suivant la deuxieme.
En passant, si tu utilises des unsigned, le test est vrai en cas d'overflow et tout le monde est d'accord la dessus.
> Ici le test (i<Ni) est toujours vrai, ce qui semble déranger g++.
Ca ne le derange pas. J'ai pas verifie exactement ce qu'il fait -- et
encore moins cherche a le faire version par version -- mais voici ma
comprehension des choses.
Le test "i < i - 2" (qui est en cause ici apres inlining) est un
comportement indefini. Face a de tels comportements, il y a -- au moins --
deux ecoles.
Celle qui dit "le compilateur peut faire n'importe quoi et il faut en
profiter pour optimiser le cas defini". Donc supprimer le test.
La deuxieme dit "C est un langage de base niveau, il faut faire ce qui est
naturel pour la machine cible, c'est a dire que le test doit etre vrai en
cas d'overflow; d'autant plus que c'est le comportement historique des
compilateurs C. Le comportement est formellement indefini mais c'est pour
permettre une implementation naturelle du C sur des machines exotiques, pas
pour laisser faire n'importe quoi sous pretexte d'optimisations".
Par defaut, g++ se comporte suivant la premiere ecole, mais donne un
warning. Il y a un flag (-fwrapv si j'ai bonne memoire) qui le fait se
comporter suivant la deuxieme.
En passant, si tu utilises des unsigned, le test est vrai en cas
d'overflow et tout le monde est d'accord la dessus.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
> Ici le test (i<Ni) est toujours vrai, ce qui semble déranger g++.
Ca ne le derange pas. J'ai pas verifie exactement ce qu'il fait -- et encore moins cherche a le faire version par version -- mais voici ma comprehension des choses.
Le test "i < i - 2" (qui est en cause ici apres inlining) est un comportement indefini. Face a de tels comportements, il y a -- au moins -- deux ecoles.
Celle qui dit "le compilateur peut faire n'importe quoi et il faut en profiter pour optimiser le cas defini". Donc supprimer le test.
La deuxieme dit "C est un langage de base niveau, il faut faire ce qui est naturel pour la machine cible, c'est a dire que le test doit etre vrai en cas d'overflow; d'autant plus que c'est le comportement historique des compilateurs C. Le comportement est formellement indefini mais c'est pour permettre une implementation naturelle du C sur des machines exotiques, pas pour laisser faire n'importe quoi sous pretexte d'optimisations".
Par defaut, g++ se comporte suivant la premiere ecole, mais donne un warning. Il y a un flag (-fwrapv si j'ai bonne memoire) qui le fait se comporter suivant la deuxieme.
En passant, si tu utilises des unsigned, le test est vrai en cas d'overflow et tout le monde est d'accord la dessus.
Fais-je une ânerie que je ne vois pas, ou bien est-ce g++ ?
Apparemment c'est g++ :
ouf ;) merci
a+ Jacques
jz
Jean-Marc Bourguet a écrit :
Merci pour la réponse détaillée.
Le test "i < i - 2" (qui est en cause ici apres inlining) est un comportement indefini. Face a de tels comportements, il y a -- au moins -- deux ecoles.
En fait ici c'est dans le sens i-2<i que le warning apparaît. Par contre là où ça devient vraiment surprenant, c'est que en remplaçant -2 par -1 le warning disparaît.
Donc "i-2<i" risquerait d'être indéfini en cas de débordement (ça je conçois), mais pas "i-1<i" ?
J'ai du mal à percevoir la logique.
A+ Jacques
Jean-Marc Bourguet a écrit :
Merci pour la réponse détaillée.
Le test "i < i - 2" (qui est en cause ici apres inlining) est un
comportement indefini. Face a de tels comportements, il y a -- au moins --
deux ecoles.
En fait ici c'est dans le sens i-2<i que le warning apparaît. Par contre
là où ça devient vraiment surprenant, c'est que en remplaçant -2 par -1
le warning disparaît.
Donc "i-2<i" risquerait d'être indéfini en cas de débordement (ça je
conçois), mais pas "i-1<i" ?
Le test "i < i - 2" (qui est en cause ici apres inlining) est un comportement indefini. Face a de tels comportements, il y a -- au moins -- deux ecoles.
En fait ici c'est dans le sens i-2<i que le warning apparaît. Par contre là où ça devient vraiment surprenant, c'est que en remplaçant -2 par -1 le warning disparaît.
Donc "i-2<i" risquerait d'être indéfini en cas de débordement (ça je conçois), mais pas "i-1<i" ?
J'ai du mal à percevoir la logique.
A+ Jacques
Jean-Marc Bourguet
jz writes:
Jean-Marc Bourguet a écrit :
Merci pour la réponse détaillée.
> Le test "i < i - 2" (qui est en cause ici apres inlining) est un > comportement indefini. Face a de tels comportements, il y a -- au moins -- > deux ecoles.
En fait ici c'est dans le sens i-2<i que le warning apparaît. Par contre là où ça devient vraiment surprenant, c'est que en remplaçant -2 par -1 le warning disparaît.
Donc "i-2<i" risquerait d'être indéfini en cas de débordement (ça je conçois), mais pas "i-1<i" ?
Je ne connais pas leur raisonnement. Une possibilite est qu'ils ne donnent pas de warnings parce que le cas avec -1 est trop commum de maniere legitime -- et un warning donne trop souvent quand le code est legitime perds beaucoup de son interet. Une autre est que le cas avec -1 est traite de maniere particuliere pour d'autres raisons et que personne n'a pense a mettre le warning dans ce chemin d'execution la.
> Le test "i < i - 2" (qui est en cause ici apres inlining) est un
> comportement indefini. Face a de tels comportements, il y a -- au moins --
> deux ecoles.
En fait ici c'est dans le sens i-2<i que le warning apparaît. Par contre là
où ça devient vraiment surprenant, c'est que en remplaçant -2 par -1
le warning disparaît.
Donc "i-2<i" risquerait d'être indéfini en cas de débordement (ça je
conçois), mais pas "i-1<i" ?
Je ne connais pas leur raisonnement. Une possibilite est qu'ils ne donnent
pas de warnings parce que le cas avec -1 est trop commum de maniere
legitime -- et un warning donne trop souvent quand le code est legitime
perds beaucoup de son interet. Une autre est que le cas avec -1 est traite
de maniere particuliere pour d'autres raisons et que personne n'a pense a
mettre le warning dans ce chemin d'execution la.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
> Le test "i < i - 2" (qui est en cause ici apres inlining) est un > comportement indefini. Face a de tels comportements, il y a -- au moins -- > deux ecoles.
En fait ici c'est dans le sens i-2<i que le warning apparaît. Par contre là où ça devient vraiment surprenant, c'est que en remplaçant -2 par -1 le warning disparaît.
Donc "i-2<i" risquerait d'être indéfini en cas de débordement (ça je conçois), mais pas "i-1<i" ?
Je ne connais pas leur raisonnement. Une possibilite est qu'ils ne donnent pas de warnings parce que le cas avec -1 est trop commum de maniere legitime -- et un warning donne trop souvent quand le code est legitime perds beaucoup de son interet. Une autre est que le cas avec -1 est traite de maniere particuliere pour d'autres raisons et que personne n'a pense a mettre le warning dans ce chemin d'execution la.