Что делает -D_DEFAULT_SOURCE?

Раньше я получал предупреждения от gcc -std=c99, что usleep() был объявлен неявно. Затем я наткнулся на qaru.site/info/287773/..., что привело меня к использованию -D_BSD_SOURCE. Однако теперь gcc сообщает мне, что -D_BSD_SOURCE устарел, и вместо этого я должен использовать -D_DEFAULT_SOURCE.

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

Почему -D_BSD_SOURCE устарел? Почему используется -D_DEFAULT_SOURCE? И что он делает?

Я сделал некоторый googling, и результаты просто заполнены людьми, использующими его, чтобы закрыть gcc вверх. Я не мог понять, почему -D_BSD_SOURCE устарел, просто так.

Ответ 1

руководство glibc описывает каждый макрос теста функции (FTM), включая _DEFAULT_SOURCE:

Если вы определяете этот макрос, большинство функций включаются отдельно Расширения X/Open, LFS и GNU: эффект заключается в том, чтобы включить функции из 2008 версия POSIX, а также некоторые функции BSD и SVID без отдельного макроса проверки функции для их управления. Определение этого макроса, самостоятельно и без использования параметров компилятора, таких как -ansi или -std=c99, имеет тот же эффект, что и определение каких-либо макросов функциональных тестов; определяя его вместе с другими макросами проверки функций или когда параметры такие как -ansi, позволяют использовать эти функции, даже если другие в противном случае они могут быть отключены.

Эта статья LWN.net о FTM дает нам обоснование (среди других, возможно, интересных):

Первоначальное намерение, похоже, состояло в том, что в каждом из glibc файлы заголовков, в которых используются FTM, только один из __USE_* внутренних макросы должны определять воздействие какого-либо конкретного определения. Кроме того, макросы не должны использоваться во вложенных #ifdefдирективы. Проверка файлов заголовков glibc быстро показывает, что реальность далека от намерения, ситуация, которая привела Роланда McGrath предложить, что настало время для крупной очистки все возвращается к предполагаемой ситуации. Роланд считал, что эта задача может быть упрощены путем устранения FTM _BSD_SOURCE и _SVID_SOURCEкоторые, хотя исторически они имели цель, перестали быть полезно в наши дни. Более того, сказал он, единственные макросы, которые необходимы для современного исходного кода - те, которые относятся к формальным стандартам плюс _GNU_SOURCE.

Джозеф Майерс должным образом обязался с серией патчей для реализации первые шаги в этой работе. Консервативный подход, поощряемый Роланд означал, что отказ от _BSD_SOURCE и _SVID_SOURCE FTMs происходит через две версии glibc. Версия 2.19 glibc добавила новую FTM, _DEFAULT_SOURCE. Определение этого макроса приводит к тому, что определения по умолчанию отображаются, даже если явные определение других макросов приведет к тому, что этого не произойдет. Эффект определения этого макроса эквивалентно эффекту явно определение трех макросов в более ранних версиях glibc:

cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809C

Итак, если вам нужно определить _BSD_SOURCE или _SVID_SOURCE, просто определите _DEFAULT_SOURCE тоже. glibc версии <= 2.18 не заботятся об этом, а версии >= 2.19 не предупреждают, если определены оба или все три.

Ответ 2

Мне нужна переносимость за пределами linux и за пределами glibc, и мне не нравится # ifdef. так:

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