2010-07-28 4 views
10

Diese einfache C-Datei:unistd.h und c99 auf Linux

#include <unistd.h> 

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

... wenn normalerweise kompiliert, funktioniert gut:

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

... aber wenn in C99-Modus kompiliert, gibt eine Warnung:

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

Die resultierende O-Datei ist in Ordnung, und die Verknüpfung funktioniert. Ich möchte nur die Warnung loswerden. Ich kann dies auf eine hacky Weise erreichen, indem ich Deklarationen in meine eigene .h-Datei setze.

Was bedeutet C99, dass die Deklarationen in unistd.h nicht enthalten sind? Kann dies überwunden werden, ohne die Nettigkeit von C99 aufzugeben?

Ich sehe das gleiche Problem für andere Standard-Bibliotheken.

Antwort

15

Sie müssen möglicherweise einige Makros in einer particluar Weise definieren, den Prototyp für gethostname()

Von man gethostname zu erhalten:

Feature-Test-Makro Anforderungen an glibc (siehe feature_test_macros (7)):

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

So:

#define _BSD_SOURCE 

#include <unistd.h> 

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

Die blutigen Details:

Wenn Sie die Option -std-c99 Sie angeben, dann features.h (die implizit durch unistd.h enthalten) zur Einrichtung _BSD_SOURCE so ausfällt, dass der Prototyp für gethostname() wird aufgenommen . Wenn Sie jedoch -std=c99 angeben, wird der Compiler automatisch __STRICT_ANSI__ definieren, was wiederum dazu führt, dass features.h_BSD_SOURCE nicht definiert, es sei denn, Sie erzwingen es mit Ihrer eigenen Feature-Makrodefinition (wie oben).

+0

+1 Sehr gründliche Behandlung. –

+1

+1 für eine Antwort. -10 für die '#define_BSD_SOURCE'. Bitte verwenden Sie '#define _XOPEN_SOURCE 500' oder besser noch in der Baukette:' cc -D_XOPEN_SOURCE = 500 ... '. Nun, wenn irgendeine Art von Portabilität gewünscht wird. – Dummy00001

+0

Wie bei meiner Antwort auf Luther - 'Mann gethostname' auf meinem Red Hat-System erwähnt keine Feature Test Makro Anforderungen. Jeder hat eine Idee warum? – slim

10

gethostname() ist keine C-Standardfunktion (im C99-Standard wird sie nirgends erwähnt), daher ist das Symbol beim Kompilieren zum Standard nicht korrekt definiert. Wenn Sie die gcc Toolchain verwenden, verwenden Sie -std=gnu99 und Sie erhalten das von Ihnen gewünschte Verhalten.

Alternativ dazu, <features.h> scheint es, als ob Sie -D_GNU_SOURCE oder -D_XOPEN_SOURCE=500 verwenden könnten, um das gewünschte Verhalten zu erhalten.

+0

Obwohl ich eine andere Antwort akzeptiert habe, ist '-std = gnu99' die Lösung, die ich tatsächlich verwendet habe. Vielen Dank. – slim

+0

Gerade lief genau in dieses Problem und wählte auch "-std = gnu99". – Cubbi

4

Gelesen man gethostname. In den Makroanforderungen für Feature-Tests wird angegeben, dass _BSD_SOURCE (oder _XOPEN_SOURCE>500) erforderlich ist, um gethostname aus unistd.h zu ziehen.

Weiter lesen man feature_test_macros. Sie werden feststellen, dass -std=c99 schaltet __STRICT_ANSI__, die in schaltet_BSD_SOURCE.Dies bedeutet, dass Sie gethostname nicht von unistd.h erhalten können, es sei denn, Sie definieren _BSD_SOURCE erneut. Normalerweise platziere ich _GNU_SOURCE für die meisten Dinge auf meiner Kommandozeile (d. H. gcc -D_GNU_SOURCE -std=c99 file.c), wodurch auch _BSD_SOURCE eingeschaltet wird.

P.S. Die Handbuchseite enthält ein Beispielprogramm, das die aktuellen ft-Makros ausdrucken kann. Sie könnten es für einige Compilereinstellungen kompilieren und ausführen.

+0

Nichts davon ist in "Mann gethostname" auf meinem Redhat-System. Welches System gehört Ihnen? Sollte ich zusätzliche Hilfeseiten installieren? – slim