2011-02-04 9 views
16

Estoy intentando compilar un programa C en un sistema Linux. Tengo una declaración #include para stdlib.h.¿Puede -std = c99 evitar que mis #includes funcionen correctamente?

Cuando puedo compilar el programa con gcc de la siguiente manera:

gcc -std=c99 -g -o progfoo progfoo.c progbar.c 

puedo obtener advertencias sobre Implicit declaration of function [srand48, drand48, bzero, or close].

Compilar en cambio, como:

gcc -g -o progfoo progfoo.c progbar.c 

no me da las advertencias, pero sí grito de mi uso de for bucles (que era la razón de la adición de -std=c99 en el primer lugar).

Dado que man srand48 menciona incluyendo , que tengo, no estoy seguro de qué otra cosa podría ser el problema. Los bucles for no son esenciales para nada (solo fueron para ahorrar tiempo al inicializar una matriz) así que no tengo problemas para eliminarlos, pero antes de hacerlo me gustaría confirmar si el estándar c99 está reemplazando algún aspecto de mi #include declaraciones.

Estoy usando gcc 4.1.2-50 (Red Hat).

Respuesta

12

¿Puede -std = c99 evitar que mis #includes funcionen correctamente?

No, pero pueden aparecer limitaciones en su conocimiento de cómo funcionan :-)


Mientras que las funciones [sd]rand48 tienen un prototipo en stdlib.h, que están dentro de un #ifdef, al menos en mi sistema:

#if defined __USE_SVID || defined __USE_XOPEN 

Así que probablemente tenga que establecer explícitamente una de esas macros.

Sin embargo, antes de intentarlo, tenga en cuenta que no funciona. Eso es porque todo esto está controlado con gcc 's feature test macros.

Hay un conjunto de reglas muy complicado para activar o desactivar características específicas en features.h y las macros creadas allí controlan lo que los archivos de encabezado incluyen y excluyen. Las variantes __USE_* se borran y configuran en ese archivo de encabezado basado en otras macros proporcionadas por usted mismo.

Por ejemplo, para obtener __USE_SVID conjunto para que pueda utilizar srand48, es necesario proporcionar el compilador con un parámetro -D_SVID_SOURCE.

Pero quizás una forma más fácil es simplemente usar C99 con las extensiones de GNU. Para hacer eso, reemplace -std=c99 con -std=gnu99.

Y, por bzero y close, éstos se pueden obtener de strings.h y unistd.h respectivamente.

que estaba un poco confundido al principio de por qué estos compilados con -std=c99 cuando tienen absolutamente nada que ver con el C99, pero luego me di cuenta de que la bandera sólo controla lo que los encabezados estándar de C le dan.

Ni strings.h (nótese el nombre en plural, esto es, no string.h) unistd.h ni son parte de la ISO C

+2

+1, pero en realidad son macros, no variables. –

+0

Buen punto, @Matteo, tiendo a pensar en _macros_ como los que _hacen_ las cosas, como '#define halfOf (x) ((x)/2)', en oposición a solo "flags" para controlar la compilación. Pero estás en lo correcto y el uso de la "variable" de trabajo por mi cuenta puede conducir a la confusión con variables reales. Así que lo cambié según tu sugerencia. – paxdiablo

+2

Derecha. Puede ser útil saber que cuando compila sin el indicador '-std =', está pidiendo '-std = gnu89', que es C89 más extensiones GNU, por lo que el C99 equivalente a este modo es' -std = gnu99 '. – caf

6

Parece que las funciones que está utilizando no son ISO C99, por lo que cuando solicita cumplimiento estricto C99 no estarán visibles.

información aquí: https://bugzilla.redhat.com/show_bug.cgi?id=130815

La bandera -D_POSIX_C_SOURCE=200809L debería funcionar.

Ver también esta pregunta: Why can't gcc find the random() interface when -std=c99 is set?

+2

Al igual que tengo que hacer un prototipo de función para "printf" en HelloWorld.c? No creo que entiendas bien mi problema. –

+0

Está recibiendo una advertencia sobre el sistema incluye archivos (stdlib.h) si entiendo bien, no en su propio código. – Earlz

+0

Lo siento, no me di cuenta de que esas funciones no se auto escribieron porque solo escribo código C99 y nunca las he usado. Editado mi respuesta. – Kevin

1

declaraciones implícitas (donde se asume una función no declarada para volver int) ya no están permitidos en C99.

Dicho esto, gcc no abortará la compilación.

Intente incluir strings.h para bzero, ver también la respuesta de paxdiablo.

+0

Creo que esto es lo que sucede: en realidad, nada * es diferente *, pero las definiciones de funciones implícitas simplemente no se informan sin los estándares de c99. Lo que significa que mis #includes simplemente no funcionan por la razón que sea. Demonios ... –

3

El error que está recibiendo lo hace sonar como las funciones que está utilizando no son siendo declarado. ¿Estás seguro de que estás incluyendo los encabezados correctos para ellos?

Además, el uso de -std=c99 puede desactivar algunas extensiones que no forman parte del estándar. Ninguna de las funciones que mencionó es parte del estándar C. Si no puede encontrar encabezados separados para ellos, puede intentar -std=gnu99.

2

-std=c99 hace que los encabezados omitan todo lo que pueda entrar en conflicto con el uso de nombres fuera del espacio de nombres reservado C99, incluidas todas las funciones POSIX estándar. La forma portátil de solicitar que los encabezados le den las interfaces POSIX es definir _POSIX_C_SOURCE en un valor correspondiente a la versión POSIX deseada. Para la última POSIX (2008), esto significa:

#define _POSIX_C_SOURCE 200809L 

o en la línea de comandos:

-D_POSIX_C_SOURCE=200809L 

Editar: Parece las funciones que desea no están en la base de POSIX pero en el Opción XSI, por lo que debe definir _XOPEN_SOURCE en un valor apropiado (700 es la última) para obtenerlos. Esto también se puede hacer desde la línea de comandos o los archivos de origen (pero si a partir de los archivos de origen, hay que hacerlo antes de incluyendo cualquiera de las cabeceras del sistema.

1

Usted está pidiendo el cumplimiento de las normas, y no lo hace C99 defina srand48() como una función proporcionada por <stdlib.h>.

Para la biblioteca GNU C, puede solicitar funciones adicionales mediante la definición de una o más de las opciones que aparecen en el comentario de la parte superior de /usr/include/features.h, ya sea por #define antes de #include, o con -D bandera para gcc.

Para srand48() (y drand48()) es probable que quieren ya sea -D_XOPEN_SOURCE=500 o -D_SVID_SOURCE (o #define _XOPEN_SOURCE 500 etc., en los archivos de origen).

bzero() y close() debería funcionar incluso con -std=c99 si #include los archivos de cabecera documentados para ellos, que son <strings.h> y <unistd.h> respectivamente.

Cuestiones relacionadas