Pregunta Con gcc, incluya símbolos estrictamente C99, excluyendo específicamente POSIX


Estoy tomando un curso en C después de muchos años de programación. Mi instructor no está usando una máquina POSIX, y recientemente fui penalizado por usar index función en una tarea. Investigué un poco y noté que, mientras index fue una parte temprana de AT & T Unix y cumple con POSIX, no es parte del estándar C99. Me gustaría que gcc me ayude a encontrar el uso de símbolos similares. Estoy compilando en OSX con gcc 4.2 (no llvm)

Mi primera etapa de investigación consistió en darme cuenta de que mi archivo string.h envuelve el prototipo de index en la siguiente verificación para macros de prueba de características:

#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)

Después de cavar un poco, encontré esto (en mi /usr/include/sys/cdefs.h)

 /* STRICT  Defining _POSIX_C_SOURCE or _XOPEN_SOURCE restricts the
 *      available APIs to exactly the set of APIs defined by the
 *      corresponding standard, based on the value defined.
 *
 *      A correct, portable definition for _POSIX_C_SOURCE is 200112L.
 *      A correct, portable definition for _XOPEN_SOURCE is 600L.
 */

Y así con este comando gcc:

gcc -D _POSIX_C_SOURCE=200112L -pedantic -Wall -std=c99 -o myExec ./mySource.c

yo hacer obtener una advertencia decente:

warning: incompatible implicit declaration of built-in function ‘index’

Esto me confunde, y Quiero hacer que el programa no se vincule también. La razón por la que me confunde es, leí en opengroup.org esa definición de esa macro debería exponer Símbolos POSIX, no ocultarlos. Así que aquí está mi pregunta en una forma sucinta:

¿Cómo puedo hacer que gcc 4.2 (en OSX 10.6) compile y vincule mi programa en un entorno que es estrictamente C99 con sin símbolos adicionales ¿disponible?

Idealmente, quiero advertencias durante la compilación y la falta de enlace. Espero que la respuesta no implique decirle a gcc que a.m escribiendo código POSIX, cuando creo que es lo opuesto a lo que quiero decir. ¿Qué no estoy entendiendo?


11
2017-08-13 07:51


origen


Respuestas:


  1. No vas a obtener un error de enlace, lo siento. Las bibliotecas no funcionan de esa manera. los index función es una parte de la biblioteca estándar. La biblioteca estándar admite múltiples versiones de C (y POSIX) al mismo tiempo, y las macros seleccionan qué prototipos se exponen.

  2. los -ansi bandera es equivalente a -std=c89, así que deja de hacer eso.

  3. Tienes razón en que _POSIX_C_SOURCE expone funcionalidad adicional, pero también especifica cual version de la funcionalidad para exponer. Definiendo _POSIX_C_SOURCE=200112L significa que index aparece en <strings.h> en lugar de <string.h>. Todavía está allí. Especificar el POSIX 2008 se deshará de index en su totalidad, ya que se eliminó de versiones posteriores del estándar POSIX.

  4. Ahí es una macro que significa "solo ANSI C", y eso es _ANSI_SOURCE.

  5. Puede obtener un error de compilación (pero no un error de enlace) al agregar -Werror-implicit-function-declaration.

$ gcc -Werror-implicit-function-declaration \
    -D_ANSI_SOURCE -pedantic -Wall -std = c99 ...
error: declaración implícita de función 'índice'

Esto parece funcionar bien en todas las combinaciones OS X 10.5 / 10.8, GCC 4.0 / 4.2.


11
2017-08-13 08:38



Para obtener un entorno C99, pase las banderas -std=c99 -pedantic a gcc. Esto no debería definir ninguna macro adicional de prueba de características.

Sin embargo, tenga en cuenta que esto solo omite el declaraciones, porque esos invaden el espacio de nombres reservado por el programador C99. Es probable que los símbolos reales todavía estén disponibles; no deberían afectar la compilación de un programa C99 correcto porque tienden a ser símbolos "débiles", pero no forzarán un error si los declaras tú mismo y los usas.


1
2017-08-13 07:55



Para el registro: con icc Lo encontré más útil para hacer

icc -no-gcc -diag-enable port-win -fabi-version=2 -std=c99 ...

que omitirá todo el vudú específico de gcc en los archivos de encabezado del sistema y advertirá sobre POSIXismos que no existen en Windows.

En cuanto a arrojar un error, solo usaría -Werror.

Desafortunadamente, gcc no puede desactivar el procesamiento de atributos específicos de gnu en los archivos de encabezado del sistema. Y, aún más desafortunado, la versión declarada de gcc no admite el -Werror=<diagnostic> sintaxis para arrojar errores solo sobre ciertas advertencias.

Entonces, en esencia, la combinación del compilador y la versión que usted indica realmente no puede ayudarlo con lo que desea.


1
2017-08-13 08:20