web-dev-qa-db-fra.com

Quel est le but d'utiliser -pedantic dans le compilateur GCC / G ++?

Cette note dit:

-ansi: indique au compilateur d'implémenter l'option de langage ANSI. Cela désactive certaines "fonctionnalités" de GCC incompatibles avec la norme ANSI.

-pedantic: utilisé avec -ansi, cela indique au compilateur de se conformer strictement à la norme ANSI, en rejetant tout code non conforme.

Tout d'abord:

  • Quel est le but de la -pedantic et -ansi options du compilateur GCC/G ++ (je ne comprends pas la description ci-dessus)?
  • Quelqu'un peut-il me dire les bonnes circonstances pour utiliser ces deux options?
  • Quand devrais-je les utiliser?
  • Sont-ils importants?
126
huahsin68

Les compilateurs GCC essaient toujours de compiler votre programme si cela est possible. Cependant, dans certains cas, les normes C et C++ spécifient que certaines extensions sont interdites. Les compilateurs conformes tels que gcc ou g ++ doivent émettre un diagnostic lorsque ces extensions sont rencontrées. Par exemple, l’option -pedantic du compilateur gcc force gcc à émettre des avertissements dans de tels cas. L'utilisation de l'option plus stricte -pedantic-errors Convertit de tels avertissements de diagnostic en erreurs entraînant l'échec de la compilation à ces points. Seules les constructions non ISO qui doivent être signalées par un compilateur conforme généreront des avertissements ou des erreurs.

75
Wazery

Je l'utilise tout le temps dans mon codage.

Le -ansi drapeau est équivalent à -std=c89. Comme indiqué, il désactive certaines extensions de GCC. Ajouter -pedantic désactive plusieurs extensions et génère davantage d'avertissements. Par exemple, si vous avez un littéral de chaîne de plus de 509 caractères, alors -pedantic met en garde à ce sujet car il dépasse la limite minimale requise par la norme C89. En d’autres termes, chaque compilateur C89 doit accepter des chaînes d’une longueur de 509; ils sont autorisés à accepter plus longtemps, mais si vous êtes pédant, il n'est pas portable d'utiliser des chaînes plus longues, même si un compilateur est autorisé à accepter des chaînes plus longues et, sans les avertissements pédants, GCC les acceptera également.

97
Jonathan Leffler

-ansi est un commutateur obsolète qui demande au compilateur de compiler conformément à la révision obsolète vieille de 30 ans du standard C , ISO/IEC 9899: 1990 , qui est essentiellement une nouvelle image de marque du standard ANSI X3.159-1989 "Langage de programmation C . Pourquoi est-ce obsolète? Parce qu'après la publication de l'ISO C90 par l'ISO, l'ISO a pris en charge la normalisation C, et tous les corrigenda techniques en C90 ont été publiés par l'ISO. est plus apte à utiliser le -std=c90.

Sans ce commutateur, les derniers compilateurs C de GCC seront conformes au langage C normalisé dans ISO/IEC 9899: 2011 ou à la dernière révision 2018.

Malheureusement, certains vendeurs de compilateurs paresseux estiment qu’il est acceptable de s’en tenir à une révision standard obsolète plus ancienne, pour laquelle le document de normalisation n’est même pas disponible auprès des organismes standard.

L'utilisation du commutateur permet de s'assurer que le code doit être compilé dans ces compilateurs obsolètes.


Le -pedantic est intéressant. En l'absence de -pedantic, même lorsqu'une norme spécifique est demandée, GCC autorisera quand même certaines extensions non acceptables dans la norme C. Considérons par exemple le programme

struct test {
    int zero_size_array[0];
};

Le C11 draft n1570, paragraphe 6.7.6.2p1 dit :

En plus des qualificateurs de type facultatifs et du mot clé static, [and] peut délimiter une expression ou *. S'ils délimitent une expression (qui spécifie la taille d'un tableau), l'expression doit avoir un type entier. Si l'expression est une expression constante, , sa valeur doit être supérieure à 0. [...]

La norme C exige que la longueur du tableau soit supérieure à zéro; et ce paragraphe est dans le contraintes; la norme dit ce qui suit 5.1.1.3p1 :

Une implémentation conforme doit produire au moins un message de diagnostic (identifié de manière définie par l'implémentation) si une unité de traduction en cours de prétraitement ou une unité de traduction contient une violation d'une règle ou contrainte de syntaxe, même si le comportement est aussi explicitement spécifié comme indéfini ou implémentation. défini. Les messages de diagnostic ne doivent pas nécessairement être produits dans d'autres circonstances.9)

Cependant, si vous compilez le programme avec gcc -c -std=c90 pedantic_test.c, aucun avertissement n'est produit.

-pedantic oblige le compilateur à se conformer à la norme C ; alors maintenant, il va produire un message de diagnostic, comme requis par la norme:

gcc -c -pedantic -std=c90 pedantic_test.c
pedantic_test.c:2:9: warning: ISO C forbids zero-size array ‘zero_size_array’ [-Wpedantic]
     int zero_size_array[0];
         ^~~~~~~~~~~~~~~

Ainsi, pour une portabilité maximale, la spécification de la révision standard ne suffit pas, vous devez également utiliser -pedantic (ou -pedantic-errors) afin de s’assurer que GCC se conforme effectivement à la lettre de la norme.


La dernière partie de la question concernait l'utilisation de -ansi avec C++ . ANSI n’a jamais normalisé le langage C++ - l’adoptant uniquement à partir de l’ISO, ce qui est aussi logique que de dire "l’anglais normalisé par la France". Cependant, GCC semble toujours l’accepter pour C++, aussi stupide que cela puisse paraître.

20
Antti Haapala

Fondamentalement, il sera beaucoup plus facile de compiler votre code sous d’autres compilateurs qui implémentent également le standard ANSI et, si vous choisissez bien les bibliothèques/appels api que vous utilisez, sous d’autres systèmes/plates-formes d’exploitation.

Le premier désactive les fonctionnalités spécifiques de GCC. (-ansi) Le second se plaindra de tout ce qui n’adhère pas à la norme (pas seulement les fonctionnalités spécifiques de GCC, mais aussi vos constructions.) (-pedantic).

14
Francisco Soto

Si votre code doit être portable, alors vous pouvez vérifier qu'il compile sans aucune extension gcc ou autre fonctionnalité non standard. Si votre code est compilé avec -pedantic -ansi alors, en théorie, il devrait compiler OK avec n’importe quel compilateur standard ANSI.

6
Paul R

Si vous écrivez du code qui, selon vous, devrait être compilé sur une grande variété de plates-formes, avec plusieurs compilateurs différents, utiliser ces indicateurs vous aidera à éviter de produire un code compilé sous GCC.

3

D'autres ont suffisamment répondu. Je voudrais juste ajouter quelques exemples d'extensions fréquentes:

La fonction main renvoie void. Ceci n'est pas défini par la norme, ce qui signifie que cela ne fonctionnera que sur certains compilateurs (y compris GCC), mais pas sur d'autres. À propos, int main() et int main(int, char**) sont les deux signatures définies par la norme.

Une autre extension populaire est la possibilité de déclarer et de définir des fonctions dans d’autres fonctions:

void f()
{
    void g()
    {
       // ...
    }

    // ...
    g();
    // ...
}

Ceci est non standard. Si vous voulez ce genre de comportement, jetez un œil à C++ 11 lambdas

1
Enn Michael

Pedantic fait en sorte que le compilateur gcc rejette toutes les extensions GNU C, pas seulement celles qui le rendent compatible ANSI.

0
Martin Konecny