6
votes

G ++ Compiler: drapeau d'optimisation ajoute un message d'avertissement

J'ai remarqué ce comportement intéressant du compilateur g ++, si j'ajoute un drapeau A -O3 au compilateur, je reçois xxx pré>

Cependant, lorsque je n'utilise pas d'optimisation et utilise plutôt un débogage. drapeau -g je n'ai aucun avertissement du tout. Maintenant, je fais plus confiance au compilateur lorsque le drapeau -g est activé; Cependant, je me demande si c'est un comportement bien défini qui devrait être attendu? p>

Pour plus de clarté, le code qui cause ceci est quelque chose dans ces lignes: P>

 void getAValueForX( int *x )
 {
     *x = 4;
 }


3 commentaires

poster le code qui provoque l'avertissement


OK mis à jour avec un exemple concret.


Avec X étant global, tout ce qui accède à X peut le faire avant qu'il ne soit attribué une valeur. Soit vous avez simplifié l'exemple trop loin, soit le type d'analyse requis pour prouver que cela ne serait pas au-delà de la portée et de la capacité de l'optimisateur. L'avertissement est juste un effet secondaire de l'optimisation, il a la possibilité de vous avertir de vous en prévenir.


7 Réponses :


1
votes

Mes drapeaux de compilateur:

CFLAGS=-W -Wall\
 -Wno-non-template-friend\
 -Wold-style-cast\
 -Wsign-promo\
 -Wstrict-null-sentinel\
 -Woverloaded-virtual
# -Weffc++


0 commentaires

18
votes

c'est attendu. Les optimisations provoquent une analyse de code spécifique à exécuter et c'est comment GCC trouve les variables non initialisées. C'est dans la page manuelle:

. . . Ces avertissements dépendent de l'optimisation

http://gcc.gnu.org/onlinedocs/gcc/warning- Options.html


1 commentaires

+1 pour le lien manuel; l'explique tout. Qui est probablement pourquoi votre réponse était tellement plus courte que la mienne;)



3
votes

Ceci est en fait très courant avec GCC. Et oui, cela doit être attendu.

Aussi loin que j'ai compris, afin d'optimiser, le compilateur génère beaucoup de métriques et transformer le code (ou, plus précisément, la représentation qu'il a du code) d'une manière qui permet la détection d'une inaidifiée ou inutilisée. Variables pour exemples (il y a quelques autres avertissements comme ça, je ne me souviens pas de la liste).

Faire la même chose sans optimisation nécessiterait de faire, puis de décoller toute cette analyse. Cela ralentira de manière significative la compilation sans objectif (surtout comme, en débogage, le compilateur n'est pas supposé réorganiser le code).


0 commentaires

1
votes

Oui, c'est un comportement bien défini. Lorsque l'optimiseur de GCC n'est pas activé, il ne fait pas certains types de vérification de chemin d'exécution (afin d'éviter la pénalité de performance de faire ce type de chèques). Certaines situations, telles que l'utilisation de variables inaidifiées, ne peuvent être détectées que lorsque ces contrôles supplémentaires sont effectués. Par conséquent, avec -O0 , GCC est incapable d'avertir ces conditions.


0 commentaires

1
votes

Eh bien, le compilateur peut déplacer des choses à optimiser peut causer des problèmes et conduire à un comportement non défini (comme indiqué par les états manuels ci-dessous); Je pense qu'il serait utile de voir le code pour essayer de donner un sens.

Les raccourcis pris par le code optimisé peut occasionnellement produire surprenant Résultats: certaines variables que vous avez déclaré peut ne pas exister du tout; flux de contrôle peut avancer brièvement où vous n'avez pas attendez-y; Certaines déclarations peuvent ne pas être exécuté parce qu'ils calculent constamment les résultats ou leurs valeurs étaient déjà à portée de main; Certaines déclarations peuvent exécuter à différents endroits parce qu'ils étaient déplacé de boucles.


1 commentaires

Cela n'a rien à voir avec si les choses sont déplacées. Avec l'optimisation désactivée, le compilateur n'effectue jamais l'analyse susceptible de détecter des variables ininitialisées. L'optimisation ne sera jamais cause une variable pour ne pas être initialisée.



3
votes

L'analyse de flux de code que l'optimiseur effectue lui permet de détecter des problèmes potentiels que la compilation normale (et plus rapide) ne peut pas détecter. Le problème était toujours là, le compilateur n'a tout simplement pas vérifié.

Même lorsque cet avertissement est émis, il peut en fait ne pas être un problème en raison de l'utilisation réelle de la fonction dans la pratique; Le compilateur supposera que toutes les valeurs possibles des types de ses arguments (et toutes les variables externes utilisées dans la fonction) peuvent se produire dans toutes les combinaisons possibles - entraînant au moins un chemin dans lequel la variable est utilisée sans être attribuée de valeur. Votre utilisation réelle aura un ensemble plus restrictif d'états possibles, de sorte que le chemin peut ne jamais se produire dans la pratique. La solution simple consiste à initialiser la variable si seulement pour fermer le compilateur - cela ne vous coûtera rien.

J'utilise toujours l'optimiseur comme une forme d'analyse statique du pauvre homme, même lorsque je n'ai finalement pas l'intention de l'utiliser dans le code de production. De même, j'utilise souvent plus d'un compilateur pour la même raison. Certains compilateurs effectuent des contrôles que d'autres ne le font pas, ou ils génèrent des messages libellés différemment pour les mêmes erreurs, ce qui aide souvent à leur interprétation pour certains des messages plus obtus.

Quote:

Je fais plus confiance au compilateur quand le -g le drapeau est sur

S'il est vrai que si un compilateur a un bogue, il est probable que l'optimiseur (c'est la partie la plus complexe), pour un compilateur mature tel que GCC, ce serait une découverte très rare. Inversement, les gens trouvent souvent que leur code de travail échoue lorsqu'il est optimisé; Le plus souvent, le code a toujours été imparfait (peut-être s'appuyer sur un comportement défini indéfini ou compilateur) et l'optimisateur vient d'être exposé à cette faille. Donc, je suggère si vous trouvez votre code rompu sous l'optimisation, suspectez le code avant que le rasoir du compilateur - Occam s'applique.


1 commentaires

+1 Je trouve en essayant une variété de compilateurs peut offrir une perspective intéressante dans votre code et attirer l'attention sur des hypothèses implicites que vous avez apportées pourraient ne pas vous tenir ailleurs. Ceci est souvent négligé.



0
votes

J'ai le même problème dans mon compilateur MSVC 6. Initialisation de la variable en question, supprime la possibilité d'un mauvais chemin du point de vue du compilateur.


0 commentaires