Что означает" #define GNU SOURCE"?

сегодня мне пришлось использовать и man 3 basename (здесь) дал мне какое-то странное сообщение:

Примечания

существует две разные версии basename () - the POSIX версия, описанная выше, и версия GNU, который получает после

#define _GNU_SOURCE
#include <string.h>

мне интересно, что это #define _GNU_SOURCE означает: есть это заражение код, который я пишу с лицензией, связанной с GNU? Или он просто используется, чтобы сказать компилятору что-то вроде "Ну, я знаю, этот набор функций не POSIX, поэтому не портативный, но я хотел бы использовать его в любом случае".

если да, то почему бы не дать людям разные заголовки, вместо того, чтобы определять какой-то неясный макрос, чтобы получить одну реализацию функции или другую?

что-то также Меня беспокоит: как компилятор знает, какая функция реализация для связи с исполняемым файлом? Использует ли он это #define так же?

у кого-нибудь есть какие-то указатели, чтобы дать мне?

4 ответов


определение _GNU_SOURCE не имеет ничего общего с лицензии и все, что связано с написанием (не)переносимый код. Если вы определяете _GNU_SOURCE вы получите:

  1. доступ к множеству нестандартных функций расширения GNU/Linux
  2. доступ к традиционным функциям, которые были опущены из стандарта POSIX (часто по уважительной причине, например, заменены лучшими альтернативами или привязаны к конкретным устаревшим реализациям)
  3. доступ к низкоуровневым функции, которые не могут быть переносимыми, но которые иногда необходимы для реализации системных утилит, таких как mount, ifconfig, etc.
  4. нарушенное поведение для многих функций, заданных POSIX, где люди GNU не согласились с Комитетом по стандартам о том, как должны вести себя функции, и решили сделать свое дело.

пока вы знаете об этих вещах, это не должно быть проблемой для определения _GNU_SOURCE, но вы должны избегать его определения и вместо этого определять _POSIX_C_SOURCE=200809L или _XOPEN_SOURCE=700 когда возможно обеспечить что ваши программы портативны.

в частности, вещи из _GNU_SOURCE Что вы должны никогда используйте #2 и #4 выше.


позвольте мне ответить еще на два вопроса:

что-то также Меня беспокоит: как компилятор знает, какая реализация функции связана с исполняемым файлом? Использует ли он этот #define?

общий подход к условно #define идентификатор basename к различным именам, в зависимости от Ли _GNU_SOURCE определяется. Например:

#ifdef _GNU_SOURCE
# define basename __basename_gnu
#else
# define basename __basename_nongnu
#endif

теперь библиотека просто должна предоставить оба поведения под этими имена.

если да, то почему бы не дать людям разные заголовки, вместо того, чтобы определять какую-то неясную переменную среды, чтобы получить одну реализацию функции или другую?

часто один и тот же заголовок имел немного различное содержимое в разных версиях Unix, поэтому нет единого правильного содержимого для, скажем, <string.h> - существует много стандартов (xkcd). Существует целый набор макросов, чтобы выбрать свой любимый, так что если ваша программа ожидает один стандарт, библиотека будет соответствовать этому.


для точной информации о том, что все включено по _GNU_SOURCE документация может помочь.

из документации GNU:

макро: определен

если вы определяете этот макрос, все включено: ISO C89, ISO C99, POSIX.1, POSIX.2, расширения BSD, SVID, X/Open, LFS и GNU. В тех случаях, когда POSIX.1 конфликты с BSD, определения POSIX имеют приоритет.

из справочной страницы Linux на функция тестирования макросы:

определен

определение этого макроса (с любым значением) неявно определяет _ATFILE_SOURCE, _LARGEFILE64_SOURCE, _ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED, _POSIX_SOURCE, _POSIX_C_SOURCE с значение 200809L (200112L в версиях glibc до 2.10; 199506L в версиях glibc до 2.5; 199309L в glibc ver‐ sions до 2.1) и _XOPEN_SOURCE с стоимость 700 (600 в версиях glibc до 2.10; 500 в версиях glibc до 2.2). Кроме того, различные расширения GNU также уязвимый.

начиная с glibc 2.19, определение _GNU_SOURCE также имеет эффект неявное определение _DEFAULT_SOURCE. В версиях glibc до 2.20 определение _GNU_SOURCE также имело эффект неявное определение _BSD_SOURCE и _SVID_SOURCE.

Примечание: _GNU_SOURCE необходимо определить до включая заголовочные файлы, чтобы соответствующие заголовки включали функции. Например:

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
...

_GNU_SOURCE также можно включить для каждой компиляции с помощью -D флаг:

$ gcc -D_GNU_SOURCE file.c

(-D не относится к _GNU_SOURCE но любой макрос будет определен таким образом).


из некоторого списка рассылки через google:

посмотрите на включение/функции glibc.h:

_GNU_SOURCE все вышеперечисленное, плюс расширения GNU.

Что означает, что он позволяет все это:

STRICT_ANSI, _ISOC99_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED, _LARGEFILE_SOURCE, _LARGEFILE64_SOURCE, _FILE_OFFSET_BITS=N, _BSD_SOURCE, _SVID_SOURCE

таким образом, он позволяет много флагов компиляции для gcc