¿Cuál es el propósito de usar -pedantic en el compilador GCC / G ++?

136

Esta nota dice:

-ansi: le dice al compilador que implemente la opción de lenguaje ANSI. Esto desactiva ciertas "características" de GCC que son incompatibles con el estándar ANSI.

-pedantic: usado en conjunto con -ansi, esto le dice al compilador que se adhiera estrictamente al estándar ANSI, rechazando cualquier código que no sea compatible.

Lo primero es lo primero:

  • ¿Cuál es el propósito -pedanticy las -ansiopciones del compilador GCC / G ++ (no pude entender la descripción anterior)?
  • ¿Alguien puede decirme las circunstancias correctas para usar estas dos opciones?
  • ¿Cuándo debo usarlos?
  • ¿Son importantes?
huahsin68
fuente

Respuestas:

84

Los compiladores de GCC siempre intentan compilar su programa si esto es posible. Sin embargo, en algunos casos, los estándares C y C ++ especifican que ciertas extensiones están prohibidas. Los compiladores conformes como gcc o g ++ deben emitir un diagnóstico cuando se encuentran estas extensiones. Por ejemplo, la opción -pedantic del compilador gcc hace que gcc emita advertencias en tales casos. El uso de la -pedantic-errorsopción más estricta convierte dichas advertencias de diagnóstico en errores que harán que la compilación falle en esos puntos. Solo las construcciones que no son ISO que deben ser marcadas por un compilador conforme generarán advertencias o errores.

Wazery
fuente
3
Los estándares ISO C y C ++ solo "prohíben las extensiones" porque la extensión no debe cambiar el comportamiento de ningún programa conforme. El compilador no está obligado a rechazar ningún programa que use extensiones.
MM
@MM: Es importante tener en cuenta que cuando algunos compiladores aceptarían una construcción útil y otros la rechazarían, el "compromiso" del Comité era tener una implementación conforme y emitir un diagnóstico que los programadores podrían ignorar, evitando así la necesidad de que el Comité ya sea mandato o prohibir la construcción.
supercat
105

Lo uso todo el tiempo en mi codificación.

La -ansibandera es equivalente a -std=c89. Como se señaló, desactiva algunas extensiones de GCC. Agregar -pedanticdesactiva más extensiones y genera más advertencias. Por ejemplo, si tiene una cadena literal de más de 509 caracteres, -pedanticadvierte sobre eso porque excede el límite mínimo requerido por el estándar C89. Es decir, cada compilador C89 debe aceptar cadenas de longitud 509; se les permite aceptar más tiempo, pero si usted es pedante, no es portátil usar cadenas más largas, aunque un compilador puede aceptar cadenas más largas y, sin las advertencias pedantes, GCC también las aceptará.

Jonathan Leffler
fuente
-ansi desactiva algunas extensiones de GCC mientras que -pedantic desactiva más extensiones. Parece que -ansi es una regla de primer nivel y luego -pedantic es una regla más restringida. ¿Significa que con esta eliminación de dos opciones puedo hacer que mi código sea más compatible con otro compilador como Microsoft one?
huahsin68
44
@ huahsin68: bueno, más o menos. MSVC es un compilador bastante diferente de la mayoría de los demás, más adaptado a su ecosistema particular y no disponible fuera de él. Hace muchas cosas a su manera, que no es lo mismo que el estándar. Sin embargo, si permanece con los encabezados estándar, etc., MSVC y GCC son bastante similares. Sin embargo, el uso -std=c89 -pedanticsignifica que puede moverse más fácilmente entre diferentes compiladores en otras plataformas. Tan pronto como empiece a usar <windows.h>, la compatibilidad con otros sistemas se vuelve problemática.
Jonathan Leffler
2
@slf: Porque como todos los demás proveedores (aunque GNU no vende su compilador por dinero en efectivo), ¿les gustaría que utilizara sus funciones propietarias? O, más generalmente, porque consideran que las extensiones son útiles y piensan que deberían habilitarse de manera predeterminada.
Jonathan Leffler
1
Para lo que sea que valga, y JFTR , en su mayoría he dejado de usar -pedantic, pero la mayoría de mi código aún se compila OK cuando lo vuelvo a habilitar (el único programa que no estaba usando explícitamente los __int128tipos, que son pedante incorrectamente). Creo que hubo una etapa de intervención cuando GCC era demasiado ruidoso (para mi gusto) -pedantic. Acabo de probar unos 300 archivos de origen, algunos códigos de biblioteca, algunos comandos, algunos programas de prueba SO, y solo había un problema que era de esperar. Actualmente usando GCC 4.8.2 en Mac OS X 10.9.2.
Jonathan Leffler
1
@JonathanLeffler, sí, estoy preguntando cuál es el nombre de un compilador real en la práctica donde eso no funcionaría. ¿Hay incluso uno de esos compiladores?
Pacerier
23

-ansies un conmutador obsoleto que solicita al compilador que compile de acuerdo con la revisión obsoleta de 30 años del estándar C , ISO / IEC 9899: 1990 , que es esencialmente un cambio de marca del estándar ANSI X3.159-1989 "Lenguaje de programación C" . ¿Por qué es obsoleto? Porque después de que C90 fue publicado por ISO, ISO ha estado a cargo de la estandarización de C, y cualquier corrección técnica a C90 ha sido publicada por ISO. Por lo tanto, es más apto para usar el -std=c90.

Sin este cambio, los recientes compiladores GCC C se ajustarán al lenguaje C estandarizado en ISO / IEC 9899: 2011 , o la última revisión de 2018.

Desafortunadamente, hay algunos vendedores de compiladores perezosos que creen que es aceptable apegarse a una revisión estándar obsoleta más antigua, para la cual el documento de estandarización ni siquiera está disponible en los organismos estándar.

El uso del conmutador ayuda a garantizar que el código se compile en estos compiladores obsoletos.


El -pedantices uno interesante. En ausencia de -pedantic, incluso cuando se solicita un estándar específico, GCC aún permitirá algunas extensiones que no son aceptables en el estándar C. Considere por ejemplo el programa

struct test {
    int zero_size_array[0];
};

El C11 borrador n1570 párrafo 6.7.6.2p1 dice :

Además de los calificadores de tipo opcionales y la palabra clave static, [y] pueden delimitar una expresión o *. Si delimitan una expresión (que especifica el tamaño de una matriz), la expresión tendrá un tipo entero. Si la expresión es una expresión constante, tendrá un valor mayor que cero. [...]

El estándar C requiere que la longitud de la matriz sea mayor que cero; y este párrafo está en las restricciones ; El estándar dice lo siguiente 5.1.1.3p1 :

Una implementación conforme producirá al menos un mensaje de diagnóstico (identificado de una manera definida por la implementación) si una unidad de traducción o unidad de traducción de preprocesamiento contiene una violación de cualquier regla o restricción de sintaxis, incluso si el comportamiento también se especifica explícitamente como indefinido o implementación. definido. Los mensajes de diagnóstico no necesitan ser producidos en otras circunstancias.9)

Sin embargo, si compila el programa gcc -c -std=c90 pedantic_test.c, no se genera ninguna advertencia.

-pedantichace que el compilador cumpla realmente con el estándar C ; así que ahora producirá un mensaje de diagnóstico, como lo requiere el estándar:

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

Por lo tanto, para una portabilidad máxima, especificar la revisión estándar no es suficiente, también debe usar -pedantic(o -pedantic-errors) para asegurarse de que GCC realmente cumpla con la letra del estándar.


La última parte de la pregunta fue sobre el uso -ansicon C ++ . ANSI nunca estandarizó el lenguaje C ++, solo lo adoptó de ISO, por lo que tiene tanto sentido como decir "Inglés estandarizado por Francia". Sin embargo, GCC todavía parece aceptarlo para C ++, por estúpido que parezca.

Antti Haapala
fuente
44
Tenga en cuenta que ha habido más revisiones del estándar de idioma. Hoy normalmente compilo con -std=c11 -Wall -Wextra -Wpedantic -Wconversion.
Davislor
14

Básicamente, hará que su código sea mucho más fácil de compilar en otros compiladores que también implementan el estándar ANSI y, si tiene cuidado con las bibliotecas / llamadas API que usa, en otros sistemas operativos / plataformas.

El primero, desactiva las características ESPECÍFICAS de GCC. (-ansi) El segundo, se quejará de CUALQUIER COSA que no cumpla con el estándar (no solo las características específicas de GCC, sino también sus construcciones). (-pedantic).

Francisco Soto
fuente
6

Si su código necesita ser portátil , puede probar que se compila sin extensiones gcc u otras características no estándar. Si su código se compila, -pedantic -ansientonces en teoría debería compilar OK con cualquier otro compilador estándar ANSI.

Paul R
fuente
44
-pedanticno desactiva todas las extensiones, deja en un montón de cosas de doble subrayado. Por lo tanto, podría ser más exacto decir que si su código se compila -pedantic -ansi, y también parece posible que se compile en otras implementaciones, entonces se compilará.
Steve Jessop
3
Mencionas cosas de doble subrayado, esto suena interesante. ¿A qué te refieres exactamente?
huahsin68
Un ejemplo es el código de ensamblaje en línea "__asm ​​__ ()" de gcc que está bien para gcc pero ese doble guión bajo puede no funcionar en un compilador de Windows, incluso si ese compilador cumplió con el estándar.
3

Si está escribiendo el código que prevé que se compilará en una amplia variedad de plataformas, con varios compiladores diferentes, entonces usar estos indicadores usted mismo ayudará a garantizar que no produzca código que solo se compila bajo GCC.

Damien_The_Unbeliever
fuente
2
bajo algunas versiones de GCC!
Mohamed Amjad LASRI
1

Otros han respondido lo suficiente. Solo me gustaría agregar algunos ejemplos de extensiones frecuentes:

La mainfunción regresa void. Esto no está definido por el estándar, lo que significa que solo funcionará en algunos compiladores (incluido GCC), pero no en otros. Por cierto, int main()yint main(int, char**) son las dos firmas que define el estándar.

Otra extensión popular es poder declarar y definir funciones dentro de otras funciones:

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

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

Esto no es estándar. Si desea este tipo de comportamiento, consulte C ++ 11 lambdas

Enn Michael
fuente
0

Pedantic hace que el compilador gcc rechace todas las extensiones de GNU C, no solo las que lo hacen compatible con ANSI.

Martin Konecny
fuente
1
Esto es muy interesante. Usted menciona la extensión GNU C, y esas extensiones pueden estar o no en el estándar ANSI. ¿Puedo tener más información sobre esto? ¿Dónde puedo obtener esos recursos apropiados?
huahsin68