Что означает" #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
вы получите:
- доступ к множеству нестандартных функций расширения GNU / Linux
- доступ к традиционным функциям, которые были опущены из стандарта POSIX (часто по уважительной причине, например, заменены лучшими альтернативами или привязаны к конкретным устаревшим реализациям)
- доступ к низкоуровневым функции, которые не могут быть переносимыми, но которые иногда нужны для реализации системных утилит, таких как
mount
,ifconfig
и т. д.- нарушенное поведение для многих функций, определенных 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 include / features.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