Quel est le but de l'utilisation de -pedantic dans le compilateur GCC / G ++?

136

Cette note dit:

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

-pedantic: utilisé en conjonction 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 des options -pedanticet -ansidu compilateur GCC / G ++ (je n'ai pas compris la description ci-dessus)?
  • Quelqu'un peut-il me dire les bonnes circonstances pour utiliser ces deux options?
  • Quand dois-je les utiliser?
  • Sont-ils importants?
huahsin68
la source

Réponses:

84

Les compilateurs GCC essaient toujours de compiler votre programme si cela est possible. Cependant, dans certains cas, les standards 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 amène gcc à émettre des avertissements dans de tels cas. L'utilisation de l' -pedantic-errorsoption plus stricte convertit ces avertissements de diagnostic en erreurs qui entraîneront l'échec de la compilation à de tels moments. Seules les constructions non ISO qui doivent être marquées par un compilateur conforme généreront des avertissements ou des erreurs.

Wazery
la source
3
Les normes ISO C et C ++ "interdisent uniquement les extensions" en ce sens que l'extension ne doit pas modifier le comportement d'un programme conforme. Le compilateur n'est pas obligé de rejeter tout programme utilisant des extensions.
MM
@MM: Il est important de noter que lorsque certains compilateurs accepteraient une construction utile et que d'autres la rejetteraient, le "compromis" du Comité était d'avoir une mise en œuvre conforme, il devait émettre un diagnostic que les programmeurs pourraient alors ignorer, évitant ainsi au Comité de devoir soit mandater ou interdire la construction.
supercat
105

Je l'utilise tout le temps dans mon codage.

Le -ansidrapeau équivaut à -std=c89. Comme indiqué, il désactive certaines extensions de GCC. L'ajout -pedanticdésactive plus d'extensions et génère plus d'avertissements. Par exemple, si vous avez une chaîne littérale de plus de 509 caractères, vous en -pedanticavertit car elle dépasse la limite minimale requise par la norme C89. Autrement dit, chaque compilateur C89 doit accepter des chaînes de longueur 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 aussi.

Jonathan Leffler
la source
-ansi désactive certaines extensions de GCC tandis que -pedantic désactive plus d'extensions. Il semble que -ansi est une règle de premier niveau alors -pedantic est une règle plus restreinte. Cela signifie-t-il qu'avec ces deux options supprimer, je peux avoir mon code plus compatible avec un autre compilateur comme Microsoft?
huahsin68
4
@ huahsin68: enfin, plus ou moins. MSVC est un compilateur assez différent de la plupart des autres, plus adapté à son écosystème particulier et non disponible en dehors de lui. Il fait beaucoup de choses à sa manière - ce qui n'est pas la même chose que la norme. Néanmoins, si vous restez avec les en-têtes standard et ainsi de suite, MSVC et GCC sont assez similaires. Cependant, l'utilisation -std=c89 -pedanticsignifie que vous pouvez vous déplacer plus facilement entre différents compilateurs sur d'autres plates-formes. Dès que vous commencez à utiliser <windows.h>, la compatibilité avec d'autres systèmes devient problématique.
Jonathan Leffler
2
@slf: Parce que comme tous les autres fournisseurs (même si GNU ne vend pas leur compilateur contre de l'argent), ils aimeraient que vous utilisiez leurs fonctionnalités propriétaires? Ou, plus généralement, parce qu'ils considèrent les extensions utiles et pensent qu'elles devraient être activées par défaut.
Jonathan Leffler
1
Pour tout ce que cela vaut, et JFTR , j'ai pratiquement arrêté d'utiliser -pedantic, mais la plupart de mon code se compile toujours correctement lorsque je le réactive (le seul programme qui n'utilisait pas explicitement des __int128types, qui sont pédantiquement incorrects). Je pense qu'il y a eu une étape intermédiaire où GCC était trop bruyant (à mon goût) avec -pedantic. Je viens de tester environ 300 fichiers source - du code de bibliothèque, des commandes, des programmes de test SO - et il y avait juste le problème à prévoir. Vous utilisez actuellement GCC 4.8.2 sur Mac OS X 10.9.2.
Jonathan Leffler
1
@JonathanLeffler, Oui, je demande quel est le nom d'un compilateur réel dans la pratique où cela ne fonctionnerait pas? Existe-t-il même un tel compilateur?
Pacerier
23

-ansiest un commutateur obsolète qui demande au compilateur de compiler selon le 30 ans révision obsolète de la norme C , ISO / CEI 9899: 1990 , qui est essentiellement un changement de nom de la norme ANSI X3.159-1989 « Langage de programmation C . Pourquoi obsolète? Parce qu'après la publication de C90 par l'ISO, l'ISO a été en charge de la normalisation C, et tout corrigenda technique à C90 a été publié par l'ISO -std=c90.

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

Malheureusement, certains fournisseurs de compilateurs paresseux pensent 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 garantir que le code doit être compilé dans ces compilateurs obsolètes.


Le -pedanticest intéressant. En l'absence de -pedantic, même lorsqu'une norme spécifique est demandée, GCC autorisera toujours certaines extensions qui ne sont pas acceptables dans la norme C. Prenons par exemple le programme

struct test {
    int zero_size_array[0];
};

Le projet C11 n1570 paragraphe 6.7.6.2p1 dit :

En plus des qualificateurs de type facultatifs et du mot-clé static, les [et] peuvent 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, elle doit avoir une valeur supérieure à zéro. [...]

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

Une implémentation conforme doit produire au moins un message de diagnostic (identifié d'une manière définie par l'implémentation) si une unité de traduction de prétraitement ou une unité de traduction contient une violation d'une règle de syntaxe ou d'une contrainte, même si le comportement est également explicitement spécifié comme indéfini ou implémentation. défini. Les messages de diagnostic n'ont pas besoin d'ê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 généré.

-pedanticoblige le compilateur à se conformer réellement à la norme C ; alors maintenant, il produira un message de diagnostic, comme l'exige 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, spécifier la révision standard ne suffit pas, vous devez également utiliser -pedantic(ou -pedantic-errors) pour vous assurer que GCC est effectivement conforme à la lettre de la norme.


La dernière partie de la question portait sur l'utilisation -ansiavec C ++ . L'ANSI n'a jamais normalisé le langage C ++ - en l'adoptant uniquement à partir de l'ISO, cela a donc autant de sens que de dire «l'anglais normalisé par la France». Cependant, GCC semble toujours l'accepter pour C ++, aussi stupide que cela puisse paraître.

Antti Haapala
la source
4
Notez qu'il y a eu d'autres révisions de la norme linguistique. Aujourd'hui, je compile généralement avec -std=c11 -Wall -Wextra -Wpedantic -Wconversion.
Davislor
14

Fondamentalement, cela rendra votre code beaucoup plus facile à compiler sous d'autres compilateurs qui implémentent également la norme ANSI, et, si vous faites attention dans les bibliothèques / api que vous utilisez, sous d'autres systèmes d'exploitation / plates-formes.

Le premier, désactive les fonctionnalités SPÉCIFIQUES de GCC. (-ansi) Le second, se plaindra de TOUT ce qui ne respecte pas le standard (pas seulement les caractéristiques spécifiques de GCC, mais aussi vos constructions.) (-pedantic).

Francisco Soto
la source
6

Si votre code doit être portable, vous pouvez tester qu'il se compile sans extensions gcc ou autres fonctionnalités non standard. Si votre code compile avec -pedantic -ansialors en théorie, il devrait compiler OK avec n'importe quel autre compilateur standard ANSI.

Paul R
la source
4
-pedanticne désactive pas toutes les extensions, il laisse sur un tas de trucs à double soulignement. Il peut donc être plus précis de dire que si votre code compile avec -pedantic -ansi, et qu'il semble également plausible de se compiler sur d'autres implémentations, il se compilera.
Steve Jessop
3
Vous mentionnez des trucs à double soulignement, cela semble intéressant. De quoi parlez-vous exactement?
huahsin68
Un exemple est le code d'assemblage en ligne «__asm ​​__ ()» de gcc qui convient parfaitement à gcc mais ce double trait de soulignement peut ne pas fonctionner sur un compilateur Windows, par exemple, même si ce compilateur est conforme à la norme.
3

Si vous écrivez du code que vous envisagez de compiler sur une grande variété de plates-formes, avec un certain nombre de compilateurs différents, utiliser vous-même ces indicateurs vous aidera à vous assurer de ne pas produire du code qui ne se compile que sous GCC.

Damien_The_Unbeliever
la source
2
sous certaines versions de GCC!
Mohamed Amjad LASRI
1

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

La mainfonction de retour void. Ceci n'est pas défini par la norme, ce qui signifie qu'il ne fonctionnera que sur certains compilateurs (y compris GCC), mais pas sur d'autres. Au fait, int main()etint main(int, char**) sont les deux signatures que la norme définit.

Une autre extension populaire est de pouvoir déclarer et définir des fonctions dans d'autres fonctions:

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

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

Ceci n'est pas standard. Si vous voulez ce type de comportement, consultez les lambdas C ++ 11

Enn Michael
la source
0

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

Martin Konecny
la source
1
C'est tellement intéressant. Vous mentionnez l'extension GNU C, et ces extensions peuvent et peuvent ne pas être dans la norme ANSI. Puis-je avoir plus d'informations à ce sujet. Où puis-je trouver ces ressources appropriées?
huahsin68