2015-03-23 41 views
10

In precedenza stavo ricevendo avvisi da gcc -std=c99 che usleep() è stato implicitamente dichiarato. Poi mi sono imbattuto in this stackoverflow post, che mi ha portato a utilizzare -D_BSD_SOURCE. Tuttavia, ora gcc mi dice che lo -D_BSD_SOURCE è stato deprecato e dovrei usare invece -D_DEFAULT_SOURCE.Cosa fa -D_DEFAULT_SOURCE?

#warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" 

Perché -D_BSD_SOURCE è deprecato? Perché è utilizzato invece lo -D_DEFAULT_SOURCE? E cosa fa?

Ho fatto some googling e i risultati sono solo pieni di persone che lo utilizzano per chiudere gcc su. Non ho potuto scoprire perché-D_BSD_SOURCE è stato deprecato, solo che lo è.

+0

E 'successo in [glibc 2.20] (https://sourceware.org/glibc/wiki/Release/2.20#Deprecation_of__BSD_SOURCE_and__SVID_SOURCE_feature_macros). Per quanto riguarda ciò che fa, la [documentazione di glibc spiega qual è l'effetto desiderato] (http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html#index-_005fDEFAULT_005fSOURCE). –

+0

la funzione usleep() è definita nel file di intestazione: unistd.h tuttavia, per la pagina man, è obsoleto e utilizza invece nanosleep. la funzione nanosleep() è definita nel file di intestazione: time.h anche, la fase di collegamento. per gcc, necessita del parametro '-lrt' – user3629249

+0

@ user3629249 Questa [man page per librt] (http://www.unix.com/man-page/opensolaris/3lib/librt/) suggerisce che 'non è necessario che lo sviluppo di nuove applicazioni specificare -lrt', ma ora mi sono spostato su nanosleep(). – ryanmjacobs

risposta

10

Il glibc manual descrive ogni macro funzione di test (FTM) tra cui _DEFAULT_SOURCE:

Se si definisce questa macro, la maggior parte delle funzioni sono incluse a parte estensioni X/Open, LFS e GNU: l'effetto è quello di consentire caratteristiche da l'edizione 2008 di POSIX, nonché alcune caratteristiche di BSD e SVID senza una macro di test di funzionalità separata per controllarle. Definire questa macro , da sola e senza utilizzare le opzioni del compilatore come -ansi o -std=c99, ha lo stesso effetto di non definire alcuna macro di test di funzionalità; definendolo insieme ad altre macro di test di funzionalità, o quando vengono utilizzate le opzioni -ansi, come ad esempio , queste funzioni vengono attivate anche quando le altre opzioni causerebbero la disabilitazione.

This LWN.net article su FTM ci fornisce una logica (tra le altre informazioni, forse interessante):

L'intento originale sembra essere stata che, all'interno di ciascuno dei file di intestazione glibc che impiega FTM, solo una delle macro interne __USE_* dovrebbe governare l'esposizione di una particolare definizione. Inoltre, le macro non devono essere utilizzate nelle direttive nidificate . Un'ispezione dei file di intestazione di glibc mostra rapidamente che la realtà è lontana dall'intento, una situazione che ha portato Roland to suggest che era giunto il momento per una pulizia importante per riportare le cose nella situazione prevista. Roland riteneva che l'attività potesse essere semplificata con _BSD_SOURCE e _SVID_SOURCE FTM, che, sebbene storicamente avessero uno scopo, hanno smesso di essere utili in questi giorni. Più, ha detto, gli unici macro necessari per il codice sorgente moderno sono quelli che si riferiscono agli standard formali più _GNU_SOURCE.

Joseph Myers duly obliged con una serie di patch per implementare i primi passi di questo lavoro con . L'approccio conservativo incoraggiato da Roland ha fatto sì che la deprecazione degli FTM _BSD_SOURCE e _SVID_SOURCE avvenga attraverso due versioni di glibc. Versione 2.19 di glibc ha aggiunto un nuovo FTM, _DEFAULT_SOURCE.La definizione di questa macro fa sì che le definizioni predefinite vengano esposte anche quando la definizione esplicita di altre macro causerebbe che non si verifichi. L'effetto di definire questa macro è equivalente all'effetto della esplicitamente definire tre macro nelle versioni di glibc precedenti:

cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809C 

Quindi, se è necessario definire _BSD_SOURCE o _SVID_SOURCE, semplicemente definire _DEFAULT_SOURCE troppo. versioni di glibc < = 2.18 non ci interessa e versioni> = 2.19 non avvisano se entrambi o tutti e tre sono definiti.

+0

Ovviamente la vera soluzione è di evitare il deprecato 'usleep' (se possibile) e usare [' nanosleep'] (http://man7.org/linux/man-pages/man2/nanosleep.2.html) invece come la Single Unix Specification non l'ha rimosso. –

+3

@ChronoKitsune: Sì, avevo scritto qualcosa a riguardo, ma non mi ha fatto domande su questo caso specifico e quindi non è finito nella risposta. E per usare 'nanosleep()' con '-std = c99', devi anche definire un FTM, ma almeno è POSIX! – cremno

1

ho bisogno di portabilità oltre linux e oltre glibc e non mi piace # ifdef. così:

/* 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