Qual è lo scopo di usare -pedantic nel compilatore GCC / G ++?


136

Questa nota dice:

-ansi: indica al compilatore di implementare l'opzione del linguaggio ANSI. Ciò disattiva alcune "caratteristiche" di GCC che sono incompatibili con lo standard ANSI.

-pedantic: usato in combinazione con -ansiquesto, dice al compilatore di aderire rigorosamente allo standard ANSI, rifiutando qualsiasi codice non conforme.

Cominciando dall'inizio:

  • Qual è lo scopo delle opzioni -pedantice -ansidel compilatore GCC / G ++ (non riesco a capire la descrizione sopra)?
  • Qualcuno può dirmi le giuste circostanze per l'utilizzo di queste due opzioni?
  • Quando dovrei usarli?
  • Sono importanti?

Risposte:


84

I compilatori GCC cercano sempre di compilare il tuo programma, se possibile. Tuttavia, in alcuni casi, gli standard C e C ++ specificano che alcune estensioni sono vietate. Compilatori conformi come gcc o g ++ devono emettere una diagnostica quando si incontrano queste estensioni. Ad esempio, l'opzione -pedantic del compilatore gcc fa sì che gcc emetta avvisi in questi casi. L'uso -pedantic-errorsdell'opzione più rigorosa converte tali avvisi diagnostici in errori che causano il fallimento della compilazione in tali punti. Solo quei costrutti non ISO che devono essere contrassegnati da un compilatore conforme genereranno avvisi o errori.


3
Gli standard ISO C e C ++ "vietano le estensioni" in quanto l'estensione non deve modificare il comportamento di alcun programma conforme. Il compilatore non è costretto a rifiutare alcun programma che utilizza estensioni.
MM

@MM: È importante notare che quando alcuni compilatori accetterebbero un costrutto utile e altri lo respingerebbero, il "compromesso" del Comitato consisteva nel fatto che l'implementazione conforme doveva emettere una diagnostica che i programmatori potevano quindi ignorare, evitando così che il Comitato mandare o vietare il costrutto.
supercat

105

Lo uso sempre nella mia codifica.

La -ansibandiera è equivalente a -std=c89. Come notato, disattiva alcune estensioni di GCC. L'aggiunta -pedanticdisattiva più estensioni e genera più avvisi. Ad esempio, se hai una stringa letterale più lunga di 509 caratteri, ti -pedanticavverte perché supera il limite minimo richiesto dallo standard C89. Cioè, ogni compilatore C89 deve accettare stringhe di lunghezza 509; sono autorizzati ad accettare più a lungo, ma se si è pedanti, non è portatile usare stringhe più lunghe, anche se a un compilatore è consentito accettare stringhe più lunghe e, senza gli avvisi pedanti, anche GCC li accetterà.


-ansi disattiva alcune estensioni di GCC mentre -pedantic disattiva più estensioni. Sembra che -ansi sia la regola di primo livello, quindi -pedantic è una regola più limitata. Significa che con queste due opzioni rimuovi posso avere il mio codice più compatibile con altri compilatori come quello di Microsoft?
huahsin68,

4
@ huahsin68: beh, più o meno. MSVC è un compilatore piuttosto diverso dalla maggior parte degli altri, più adattato al suo particolare ecosistema e non disponibile al di fuori di esso. Fa molte cose a modo suo, il che non è lo stesso dello standard. Tuttavia, se rimani con le intestazioni standard e così via, MSVC e GCC sono abbastanza simili. Tuttavia, l'utilizzo -std=c89 -pedanticsignifica che puoi spostarti più facilmente tra diversi compilatori su altre piattaforme. Non appena si inizia a utilizzare <windows.h>, la compatibilità con altri sistemi diventa problematica.
Jonathan Leffler,

2
@slf: Perché come ogni altro fornitore (anche se GNU non vende il proprio compilatore per denaro), vorrebbero che tu utilizzassi le loro caratteristiche proprietarie? O, più in generale, perché considerano le estensioni utili e pensano che dovrebbero essere abilitate per impostazione predefinita.
Jonathan Leffler,

1
Per quanto valga la pena, e JFTR , ho smesso per lo più di usare -pedantic, ma la maggior parte del mio codice si compila ancora OK quando lo riattivo (l'unico programma che non usava esplicitamente i __int128tipi, che sono erroneamente pedanti). Penso che ci sia stata una fase intermedia in cui GCC era troppo rumoroso (per i miei gusti) -pedantic. Ho appena testato circa 300 file di origine - alcuni codici di libreria, alcuni comandi, alcuni programmi di test SO - e c'era solo il problema prevedibile. Attualmente sto usando GCC 4.8.2 su Mac OS X 10.9.2.
Jonathan Leffler

1
@JonathanLeffler, Sì, sto chiedendo qual è il nome di un vero compilatore in pratica dove non funzionerebbe? Esiste anche un compilatore del genere?
Pacerier

23

-ansiè un interruttore obsoleta che richiede il compilatore per compilare secondo il 30-year-old revisione obsoleta di standard C , ISO / IEC 9899: 1990 , che è essenzialmente un rebranding del standard ANSI X3.159-1989 "linguaggio di programmazione C . Perché obsoleto? Perché dopo che C90 è stato pubblicato da ISO, ISO è stato responsabile della standardizzazione C, e ogni correzione tecnica a C90 è stata pubblicata da ISO, quindi è più appropriato usare il file -std=c90.

Senza questo interruttore, i recenti compilatori GCC C saranno conformi al linguaggio C standardizzato in ISO / IEC 9899: 2011 o alla più recente revisione 2018.

Sfortunatamente ci sono alcuni venditori di compilatori pigri che credono che sia accettabile attenersi a una vecchia revisione standard obsoleta, per la quale il documento di standardizzazione non è nemmeno disponibile presso gli organismi standard.

L'uso dello switch aiuta a garantire la compilazione del codice in questi compilatori obsoleti.


È -pedanticinteressante. In assenza di -pedantic, anche quando viene richiesto uno standard specifico, GCC consentirà comunque alcune estensioni non accettabili nello standard C. Considera ad esempio il programma

struct test {
    int zero_size_array[0];
};

Il progetto C11 n1570 paragrafo 6.7.6.2p1 dice :

Oltre ai qualificatori di tipo opzionali e alla parola chiave static, il simbolo [e] può delimitare un'espressione o *. Se delimitano un'espressione (che specifica la dimensione di un array), l'espressione deve avere un tipo intero. Se l'espressione è un'espressione costante, deve avere un valore maggiore di zero. [...]

Lo standard C richiede che la lunghezza dell'array sia maggiore di zero; e questo paragrafo è nei vincoli ; lo standard dice il seguente 5.1.1.3p1 :

Un'implementazione conforme produce almeno un messaggio diagnostico (identificato in modo definito dall'implementazione) se un'unità di traduzione preelaborata o un'unità di traduzione contiene una violazione di qualsiasi regola o vincolo di sintassi, anche se il comportamento è anche esplicitamente specificato come non definito o implementazione- definito. I messaggi diagnostici non devono essere prodotti in altre circostanze.9)

Tuttavia, se si compila il programma con gcc -c -std=c90 pedantic_test.c, non viene prodotto alcun avviso.

-pedanticfa sì che il compilatore sia effettivamente conforme allo standard C ; così ora produrrà un messaggio diagnostico, come richiesto dallo standard:

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];
         ^~~~~~~~~~~~~~~

Pertanto, per la massima portabilità, specificare la revisione standard non è sufficiente, è inoltre necessario utilizzare -pedantic(o -pedantic-errors) per assicurarsi che GCC sia effettivamente conforme alla lettera dello standard.


L'ultima parte della domanda riguardava l'utilizzo -ansicon C ++ . ANSI non ha mai standardizzato il linguaggio C ++ - adottandolo solo dall'ISO, quindi ha senso tanto quanto dire "inglese come standardizzato dalla Francia". Comunque GCC sembra ancora accettarlo per C ++, per quanto stupido sembri.


4
Si noti che sono state apportate ulteriori revisioni dello standard linguistico. Oggi in genere compilo con -std=c11 -Wall -Wextra -Wpedantic -Wconversion.
Davislor,

14

Fondamentalmente, renderà il tuo codice molto più facile da compilare sotto altri compilatori che implementano anche lo standard ANSI e, se stai attento in quali librerie / chiamate API usi, sotto altri sistemi operativi / piattaforme.

Il primo, disattiva le caratteristiche SPECIFICHE di GCC. (-ansi) Il secondo, si lamenterà di QUALCOSA che non aderisce allo standard (non solo le caratteristiche specifiche di GCC, ma anche i tuoi costrutti.) (-pedantico).


6

Se il tuo codice deve essere portatile , puoi verificare che venga compilato senza estensioni gcc o altre funzionalità non standard. Se il tuo codice viene compilato, -pedantic -ansiin teoria dovrebbe essere compilato correttamente con qualsiasi altro compilatore standard ANSI.


4
-pedanticnon disattiva tutte le estensioni, lascia un sacco di cose con doppio trattino basso. Quindi potrebbe essere più preciso affermare che se il tuo codice viene compilato -pedantic -ansie sembra anche plausibilmente simile a quello che potrebbe essere compilato su altre implementazioni, allora verrà compilato.
Steve Jessop,

3
Citi cose con doppio trattino basso, questo sembra interessante. A cosa ti riferisci esattamente?
huahsin68,

Un esempio è il codice di assembly inline "__asm ​​__ ()" di gcc che va bene per gcc ma quella doppia sottolineatura potrebbe non funzionare su un compilatore di Windows, anche se quel compilatore era conforme allo standard.

3

Se stai scrivendo il codice che prevedi verrà compilato su una vasta gamma di piattaforme, con un numero di compilatori diversi, allora l'utilizzo di questi flag ti aiuterà ad assicurarti di non produrre codice che viene compilato solo in GCC.


2
sotto alcune versioni di GCC!
Mohamed Amjad LASRI,

1

Altri hanno risposto sufficientemente. Vorrei solo aggiungere alcuni esempi di estensioni frequenti:

La mainfunzione sta tornando void. Questo non è definito dallo standard, nel senso che funzionerà solo su alcuni compilatori (incluso GCC), ma non su altri. A proposito, int main()e int main(int, char**)sono le due firme che lo standard definisce.

Un'altra estensione popolare è la possibilità di dichiarare e definire funzioni all'interno di altre funzioni:

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

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

Questo non è standard. Se vuoi questo tipo di comportamento, dai un'occhiata a C ++ 11 lambdas


0

Pedantic lo fa in modo che il compilatore gcc rifiuti tutte le estensioni GNU C non solo quelle che lo rendono compatibile con ANSI.


1
Questo è così interessante. Si menziona l'estensione GNU C e tale estensione può e potrebbe non essere nello standard ANSI. Posso avere maggiori informazioni a riguardo. Dove posso trovare quelle risorse appropriate?
huahsin68,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.