Früher erhielt ich Abmahnungen von gcc -std=c99
das usleep()
wurde implizit deklariert. Dann bin ich über diesen Stackoverflow-Beitrag gestolpert, der mich zu use geführt hat -D_BSD_SOURCE
. Allerdings jetzt gcc
sagt mir das -D_BSD_SOURCE
ist veraltet und sollte verwendet werden -D_DEFAULT_SOURCE
stattdessen.
#warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"
Warum ist -D_BSD_SOURCE
veraltet? Warum ist -D_DEFAULT_SOURCE
stattdessen verwendet? Und was macht es?
Ich tat etwas googelnund die Ergebnisse sind nur mit Leuten gefüllt, die es zum Schließen verwenden gcc
hoch. Ich konnte es nicht herausfinden warum -D_BSD_SOURCE
ist veraltet, nur dass es so ist.
Das glibc-Handbuch beschreibt jedes Feature-Test-Makro (FTM) einschließlich _DEFAULT_SOURCE
:
Wenn Sie dieses Makro definieren, sind die meisten Funktionen außer X/Open-, LFS- und GNU-Erweiterungen enthalten: Der Effekt besteht darin, Funktionen aus der Ausgabe 2008 von POSIX sowie bestimmte BSD- und SVID-Funktionen zu aktivieren, ohne ein separates Funktionstestmakro zu steuern Sie. Das Definieren dieses Makros allein und ohne Verwendung von Compileroptionen wie z -ansi
oder
-std=c99
, hat denselben Effekt wie das Nichtdefinieren von Funktionstestmakros; Definieren Sie es zusammen mit anderen Feature-Test-Makros oder wenn Optionen wie z -ansi
verwendet werden, aktiviert diese Funktionen, selbst wenn die anderen Optionen andernfalls dazu führen würden, dass sie deaktiviert werden.
Dieser LWN.net-Artikel über FTMs liefert uns eine Begründung (neben anderen vielleicht interessanten Informationen):
Die ursprüngliche Absicht scheint darin bestanden zu haben, dass in jeder der Glibc-Header-Dateien, die FTMs verwenden, nur eine der __USE_*
interne Makros sollten die Offenlegung einer bestimmten Definition regeln. Darüber hinaus sollten die Makros nicht verschachtelt verwendet werden #ifdef
Richtlinien. Ein Blick in die glibc-Header-Dateien zeigt schnell, dass die Realität weit von der Absicht entfernt ist, eine Situation, die Roland McGrath veranlasste vorschlagen dass es Zeit für eine große Bereinigung war, um die Dinge wieder in den beabsichtigten Zustand zu bringen. Roland war der Meinung, dass diese Aufgabe vereinfacht werden könnte, indem man das eliminiert _BSD_SOURCE
und _SVID_SOURCE
FTMs, die, obwohl sie historisch einen Zweck hatten, heutzutage nicht mehr nützlich sind. Für modernen Quellcode werden nur noch solche Makros benötigt, die sich auf formale Standards plus beziehen
_GNU_SOURCE
.
Joseph Meyer ordnungsgemäß verpflichtet mit einer Reihe von Patches, um die ersten Schritte in dieser Arbeit umzusetzen. Der von Roland ermutigte konservative Ansatz bedeutete, dass die Abwertung der _BSD_SOURCE
und
_SVID_SOURCE
FTMs findet über zwei Glibc-Versionen hinweg statt. Version 2.19 von glibc hat eine neue FTM hinzugefügt, _DEFAULT_SOURCE
. Das Definieren dieses Makros bewirkt, dass die Standarddefinitionen verfügbar gemacht werden, selbst wenn die explizite Definition anderer Makros dazu führen würde, dass dies nicht geschieht. Die Wirkung der Definition dieses Makros entspricht der Wirkung der expliziten Definition von drei Makros in früheren Glibc-Versionen:
cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809C
Also, wenn Sie definieren müssen _BSD_SOURCE
oder _SVID_SOURCE
einfach definieren _DEFAULT_SOURCE
zu. Glibc-Versionen <= 2.18 kümmern sich nicht darum und Versionen >= 2.19 warnen nicht, wenn beide oder alle drei definiert sind.
Ich brauche Portabilität über Linux und Glibc hinaus, und ich mag #ifdef nicht. Also:
/* asprintf() does not appear on linux without this */
#define _GNU_SOURCE
/* gettimeofday() does not appear on linux without this. */
#define _BSD_SOURCE
/* modern glibc will complain about the above if it doesn't see this. */
#define _DEFAULT_SOURCE
Es passierte in glibc 2.20. Was es tut, die glibc-Dokumentation erklärt, was der beabsichtigte Effekt ist.
– Benutzer539810
23. März 2015 um 0:45 Uhr
Die usleep()-Funktion ist in der Header-Datei definiert: unistd.h ist jedoch laut Manpage veraltet und soll stattdessen nanosleep verwenden. die Funktion nanosleep() ist in der Header-Datei definiert: time.h auch der Link-Step. benötigt für gcc den Parameter ‘-lrt’
– Benutzer3629249
23. März 2015 um 1:29 Uhr
@ user3629249 Dies Handbuchseite für librt schlägt vor, dass
new application development need not specify -lrt
aber ja, ich bin jetzt zu nanosleep() gewechselt.– ryanmjacobs
23. März 2015 um 1:59 Uhr