2010-07-28 29 views
10

Este sencillo archivo .c:unistd.h y C99 en Linux

#include <unistd.h> 

void test() { 
    char string[40]; 
    gethostname(string,40); 
} 

... cuando se compila normalmente, funciona bien:

$ cc -Wall -c -o tmp.o tmp.c 
$ 

... pero cuando se compila en modo C99, da una advertencia:

$ cc -Wall -std=c99 -c -o tmp.o tmp.c 
tmp.c: In function `test': 
tmp.c:5: warning: implicit declaration of function `gethostname' 
$ 

El archivo .o resultante está bien, y el enlace funciona. Me gustaría deshacerme de la advertencia. Puedo lograr esto de una manera hacky, poniendo declaraciones en mi propio archivo .h.

¿Qué tiene C99 que significa que las declaraciones en unistd.h no se incluyen? ¿Se puede superar esto, sin renunciar a la bondad de C99?

Veo el mismo problema para otras librerías estándar.

Respuesta

15

Es posible que necesite para definir algunas macros de una manera particluar para obtener el prototipo para gethostname()

De man gethostname:

de prueba Requisitos de características de las macros para los glibc (ver feature_test_macros (7)):

gethostname(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 
    sethostname(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) 

Así:

#define _BSD_SOURCE 

#include <unistd.h> 

void test() { 
    char string[40]; 
    gethostname(string,40); 
} 

Los detalles sangrientos:

Si no se especifica la opción -std-c99, entonces features.h (que se incluye implícitamente por unistd.h) tome por defecto la configuración _BSD_SOURCE de tal manera que el prototipo para gethostname() vaya a incluirse . Sin embargo, al especificar -std=c99, el compilador define automáticamente __STRICT_ANSI__, lo que a su vez provoca que features.h no defina _BSD_SOURCE, a menos que lo fuerce con su propia definición de macro de características (como se indicó anteriormente).

+0

+1 Tratamiento muy completo. –

+1

+1 por una respuesta. -10 para el '#define _BSD_SOURCE'. Utilice '#define _XOPEN_SOURCE 500' o mejor aún en la cadena de compilación:' cc -D_XOPEN_SOURCE = 500 ... '. Bueno, eso si se desea cualquier tipo de portabilidad. – Dummy00001

+0

Al igual que con mi respuesta a Luther, 'man gethostname' en mi sistema Red Hat no menciona los requisitos de macro de prueba de características. Alguien tiene alguna idea de por qué? – slim

10

gethostname() no es una función C estándar (no se menciona en ningún lugar en el estándar C99), por lo que el símbolo no se define correctamente al compilar al estándar.

Si está utilizando la cadena de herramientas gcc, use -std=gnu99 y obtendrá el comportamiento que desea.

Como alternativa, al mirar <features.h>, parece que podría usar -D_GNU_SOURCE o -D_XOPEN_SOURCE=500 para obtener el comportamiento deseado.

+0

Aunque acepté una respuesta diferente, '-std = gnu99' es la solución que realmente utilicé. Gracias. – slim

+0

Acabo de toparme exactamente con este problema y elegí '-std = gnu99' también. – Cubbi

4

Lea man gethostname. En Requisitos de macro de prueba de características, se indica que _BSD_SOURCE (o _XOPEN_SOURCE>500) es necesario para extraer gethostname de unistd.h.

Siguiente lea man feature_test_macros. Verá que -std=c99 enciende __STRICT_ANSI__ que en apaga_BSD_SOURCE.Esto significa que no puede obtener gethostname desde unistd.h a menos que defina _BSD_SOURCE nuevamente. Normalmente coloco _GNU_SOURCE en mi línea de comando (es decir, gcc -D_GNU_SOURCE -std=c99 file.c) para la mayoría de las cosas, lo que también activa _BSD_SOURCE.

P.S. La página del manual contiene un programa de ejemplo que puede imprimir las macros ft actuales. Puede compilarlo y ejecutarlo para algunas configuraciones del compilador.

+0

Nada de eso está en 'man gethostname' en mi sistema redhat. ¿Qué sistema es el tuyo? ¿Debo instalar más páginas de manual? – slim