FEATURE_TEST_MACROS(7)

ИМЯ
feature_test_macros - макросы тестирования свойств

ОПИСАНИЕ
Макросы тестирования свойств позволяют программисту контролировать какие определения будут доступны из системных заголовочных файлов при компиляции программы.

ЗАМЕЧАНИЕ: В целях эффективности, макрос тестирования свойств должен быть определён до включения всех заголовочных файлов. Это можно сделать или в команде компиляции (cc -DМАКРОС=значение) или определив макрос в исходном коде до включения заголовочных файлов. Требование включения макроса раньше остальных заголовочных файлов возникло из-за того, что заголовочные файлы могут включаться друг в друга в любой последовательности. Например, в следующих строках определение макроса _GNU_SOURCE может не сработать, так как заголовок <abc.h> сам включает <xyz.h> (в POSIX это разрешается явным образом):

    #include <abc.h>
    #define _GNU_SOURCE
    #include <xys.h>

Некоторые макросы тестирования свойств полезны для создания переносимых приложений; они позволяют блокировать нестандартные определения. Другие макросы можно использовать для разблокировки нестандартных определений, которые по умолчанию недоступны.

Действие каждого макроса тестирования свойств, описанного далее, можно узнать из содержимого заголовочного файла <features.h>. Замечание: в приложениях не нужно явно включать <features.h> — это не приветствуется. Смотрите ЗАМЕЧАНИЯ.

  Обозначение макросов тестирования свойств в справочных страницах
Когда функции требуется определение макроса тестирования свойств в ОБЗОРЕ справочной страницы, обычно, содержится упоминание в следующем виде (этот пример взят из справочной страницы acct(2)):

    #include <unistd.h>

    int acct(const char *filename);

        Требования макроса тестирования свойств для glibc
        (см. feature_test_macros(7)):

    acct(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)

Символ || означает, что для получения объявления acct(2) из <unistd.h> нужно определить любой из следующих макросов до включения любых заголовочных файлов:

    #define _BSD_SOURCE
    #define _XOPEN_SOURCE        /* или любое значение < 500 */

Или же эквивалентные определения могут быть включены следующей командой компиляции:

    cc -D_BSD_SOURCE
    cc -D_XOPEN_SOURCE           # или любое значение < 500

Как описывается далее, некоторые макросы тестирования свойств определяются по умолчанию, поэтому макрос не всегда нужно указывать явно даже, если он приведён в ОБЗОРЕ.

В некоторых случаях в справочных страницах используется сокращённая запись требований макросов тестирования свойств (пример из readahead(2)):

    #define _GNU_SOURCE
    #include <fcntl.h>

ssize_t readahead(int fd, off64_t *offset, size_t count);

Такой формат употребляется в случаях, когда достаточно одного макроса для получения объявления функции, и этот макрос не определён по умолчанию.

  Макросы тестирования свойств, распознаваемые glibc
В следующих параграфах описаны макросы тестирования свойств, управляющие Linux glibc 2.x, где x > 0.

Если кратко:

*   Макросы, которые вам, вероятно, понадобится использовать в современном коде: _POSIX_C_SOURCE (определения из различных версий POSIX.1), _XOPEN_SOURCE (определения из различных версий SUS), _GNU_SOURCE (специальные возможности GNU и/или Linux) и _DEFAULT_SOURCE (определения, которые, обычно, включены по умолчанию).

*   Некоторые макросы определяют значения по умолчанию. То есть, хотя один или более макросов могут быть указаны как необходимые в ОБЗОР справочной страницы, возможно необязательно определять их явно. Полное описание значений по умолчанию приведены далее в этой справочной странице.

*   Определение _XOPEN_SOURCE со значением 600 и более даёт тот же эффект что и определение _POSIX_C_SOURCE со значением 200112L и больше. Если требуется

        _POSIX_C_SOURCE >= 200112L

    в макросах тестирования свойств ОБЗОРА справочной страницы, то это неявным образом тоже что и:

        _XOPEN_SOURCE >= 600

*   Определение _XOPEN_SOURCE со значением 700 и более даёт тот же эффект что и определение _POSIX_C_SOURCE со значением 200809L и больше. Если требуется

        _POSIX_C_SOURCE >= 200809L

    в макросах тестирования свойств ОБЗОРА справочной страницы, то это неявным образом тоже что и:

        _XOPEN_SOURCE >= 700

В Linux glibc распознаются следующие макросы тестирования свойств:

__STRICT_ANSI__
    Стандарт ISO C. Этот макрос неявно определяется компилятором gcc(1), если он вызывается с флагом -std=c99 или -ansi.

_POSIX_C_SOURCE
    При определении этого макроса из заголовочных файлов становится доступно следующее:

    •   При значении 1 доступны определения, удовлетворяющие POSIX.1-1990 и ISO C (1990).

    •   При значении 2 и более дополнительно доступны определения, удовлетворяющие POSIX.2-1992.

    •   При значении 199309L и более дополнительно доступны определения, удовлетворяющие POSIX.1b (расширения для реального времени).

    •   При значении 199506L и более дополнительно доступны определения, удовлетворяющие POSIX.1c (нити).

    •   (начиная с glibc 2.3.3) При значении 200112L и более доступны определения, удовлетворяющие базовой спецификации POSIX.1-2001 (за исключением расширения XSI) а также свойства C95 (начиная с glibc 2.12) и C99 (начиная с glibc 2.10). Другими словами это эквивалент определения _ISOC99_SOURCE.

    •   (начиная с glibc 2.10) При значении 200809L и более доступны определения, удовлетворяющие базовой спецификации POSIX.1-2008 (за исключением расширения XSI).

_POSIX_SOURCE
    Определение этого устаревшего макроса с любым значением эквивалентно определению _POSIX_C_SOURCE со значением 1.

    Так как этот макрос устарел, его использование, обычно, не описывается при обсуждении требований макросов тестирования свойств в справочной странице.

_XOPEN_SOURCE
    При определении этого макроса из заголовочных файлов становится доступно следующее:

    •   Определение с любым значением делает доступным определения, удовлетворяющие POSIX.1, POSIX.2 и XPG4.

    •   При значении 500 и более дополнительно доступны определения, удовлетворяющие SUSv2 (UNIX 98).

    •   (начиная с glibc 2.2) При значении 600L и более дополнительно доступны определения, удовлетворяющие SUSv3 (UNIX 03; т. е., базовой спецификации POSIX.1-2001 плюс расширение XSI), и определения C99.

    •   (начиная с glibc 2.10) При значении 700 и более дополнительно доступны определения, удовлетворяющие SUSv4 (т. е., базовой спецификации POSIX.1-2008 плюс расширение XSI).

    If __STRICT_ANSI__ не определено или определено _XOPEN_SOURCE со значением больше или равно 500 и явно не определено _POSIX_SOURCE или _POSIX_C_SOURCE, то неявно определяются следующие макросы:

    •   _POSIX_SOURCE определяется со значением 1.

    •   _POSIX_C_SOURCE определяется согласно значению _XOPEN_SOURCE:

        _XOPEN_SOURCE < 500
            _POSIX_C_SOURCE определяется со значением 2.

        500 <= _XOPEN_SOURCE < 600
            _POSIX_C_SOURCE определяется со значением 199506L.

        600 <= _XOPEN_SOURCE < 700
            _POSIX_C_SOURCE определяется со значением 200112L.

        700 <= _XOPEN_SOURCE (начиная с glibc 2.10)
            _POSIX_C_SOURCE определяется со значением 200809L.

    Также, определение _XOPEN_SOURCE со значением 500 и более даёт тот же эффект что и определение _XOPEN_SOURCE_EXTENDED.

_XOPEN_SOURCE_EXTENDED
    Если этот макрос определён вместе с _XOPEN_SOURCE, то доступны определения, соответствующие расширениям UNIX (UNIX 95) XPG4v2 (SUSv1). Определение _XOPEN_SOURCE со значением 500 и более также вызывает эффект, подобный _XOPEN_SOURCE_EXTENDED. Использование _XOPEN_SOURCE_EXTENDED в новом коде следует избегать.

    Так как определение _XOPEN_SOURCE со значением 500 и более даёт тот же эффект, что и _XOPEN_SOURCE_EXTENDED, последний (устаревший) макрос тестирования свойств, обычно, не описывается в ОБЗОРЕ справочной страницы.

_ISOC99_SOURCE (начиная с glibc 2.1.3)
    Делает доступными объявления, удовлетворяющие требованиям стандарта ISO C99.

    Ранние версии glibc 2.1.x распознавали макрос-эквивалент _ISOC9X_SOURCE (так как стандарт C99 ещё не был утверждён). Хотя использование последнего макроса не рекомендуется, glibc пока поддерживает его для обратной совместимости.

    Делает доступными определения стандарта ISO C (1990) Amendment 1 («C95»). Основным изменением в C95 была поддержка международных наборов символов.

    Вызов компилятора C с параметром -std=c99 работает также как если был бы указан этот макрос.

_ISOC11_SOURCE (начиная с glibc 2.16)
    Делает доступными объявления, удовлетворяющие требованиям стандарта ISO C11. Определение этого макроса также включает свойства C99 и C95 (подобно _ISOC99_SOURCE).

    Вызов компилятора C с параметром -std=c11 работает также как если был бы указан этот макрос.

_LARGEFILE64_SOURCE
    Делает доступными объявления альтернативного программного интерфейса, определяемого в LFS (Large File Summit) как «переходного расширение» на Single UNIX Specification (смотрите программный интерфейс состоит из набора новых объектов (т. е., функций и типов), чьи имена оканчиваются на «»64 (например, off64_t и off_t, lseek64() и lseek(), и т. д.). В новых программах не нужно указывать этот макрос; вместо него указывайте _FILE_OFFSET_BITS=64.

_LARGEFILE_SOURCE
    Данный макрос исторически используется для предоставления определённых функций (в частности, fseeko(3) и ftello(3)), которые обходят адресные ограничения раннего программного интерфейса (fseek(3) и ftell(3)), в котором для файловых смещений использовался long int. Данный макрос неявно определяется, если определён _XOPEN_SOURCE со значением больше или равным 500. В новых программах не нужно определять данный макрос; определение _XOPEN_SOURCE или _FILE_OFFSET_BITS со значением 64 является более предпочтительным механизмом для достижения того же результата.

_FILE_OFFSET_BITS
    При определении данного макроса со значением 64 ссылки на 32-битные функции и типы данных, относящиеся к файловому вводу-выводу и операциям с файловой системой, автоматически преобразуются в их 64-битные прототипы. Это полезно для выполнения ввода-вывода в огромные файлы (> 2 гигабайт) на 32-битных системах (определение данного макроса позволяет корректно написанным программам использовать огромные файлы, для чего требуется только перекомпиляция).

    64-битные системы сразу позволяют работать с файлами размером больше 2 гигабайт, и на этих системах данный макрос ничего не делает.

_BSD_SOURCE (устарел начиная с glibc 2.20)
    Определение данного макроса с любым значением приводит к доступности из заголовочных файлов определений BSD.

    В glibc до версии 2.18 включительно при определении данного макроса также отдаётся приоритет определениям BSD в ситуациях, когда имеется конфликт со стандартами. Если определён один из макросов _SVID_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED или _GNU_SOURCE, то определения BSD не используются. Начиная с glibc 2.19 при наличии макроса _BSD_SOURCE определения BSD в случае конфликта приоритета не имеют.

    Начиная с glibc 2.20 этот макрос считается устаревшим. Теперь он действует также как определение _DEFAULT_SOURCE, но при компиляции генерируется предупреждение (если также не определён _DEFAULT_SOURCE). Используйте _DEFAULT_SOURCE вместо него. Чтобы для кода, которому требуется _BSD_SOURCE в glibc 2.19 и старее и _DEFAULT_SOURCE в glibc 2.20 и новее, не выдавалось предупреждение при компиляции определите _BSD_SOURCE и _DEFAULT_SOURCE одновременно.

_SVID_SOURCE (устарел начиная с glibc 2.20)
    При определении этого макроса с любым значением из заголовочных файлов становятся доступны определения System V (SVID == System V Interface Definition; смотрите standards(7)).

    Начиная с glibc 2.20 этот макрос устарел также как _BSD_SOURCE.

_DEFAULT_SOURCE (начиная с glibc 2.19)
    Данный макрос можно определить, чтобы точно знать, что будут доступны определения «по умолчанию» даже, если умолчательные макросы отключены, что случается, когда отдельные макросы определяются явно, или компилятор вызывается в одном из своих «стандартных» режимов (например, cc -std=c99). Определение _DEFAULT_SOURCE без определения отдельных макросов или вызов компилятора в одном из его «стандартных» режимов не работают.

    Определения «по умолчанию» охватывают все, которые требуются POSIX.1-2008 и ISO C99, а также различные определения появившиеся из BSD и System V. В glibc 2.19 и старее эти значения по умолчанию приблизительно эквивалентны явному определению следующего:

        cc -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809

_ATFILE_SOURCE (начиная с glibc 2.4)
    При определении этого макроса с любым значением из заголовочных файлов становятся доступны объявления набора функций с суффиксом «at»; смотрите openat(2). Начиная с glibc 2.10 данный макрос также неявно определяется, если определён _POSIX_C_SOURCE со значением 200809L или больше.

_GNU_SOURCE
    При определении этого макроса (с любым значением) неявно определяются _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 до 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.

_REENTRANT
    В прошлом, этот макрос требовалось определять для различных библиотек C, чтобы работал многонитевой код (некоторым библиотекам C это всё ещё требуется). В glibc этот макрос также включает определения определённых реентерабельных функций.

    Однако glibc уже давно по умолчанию безопасна для нитей; начиная glibc 2.3 единственным эффектом определения _REENTRANT является включение одного или двух определений, которые также включаются определением _POSIX_C_SOURCE со значением 199606L или больше.

    В настоящий момент _REENTRANT устарел. В glibc 2.25 и новее определение _REENTRANT эквивалентно определению _POSIX_C_SOURCE со значением 199606L. Если выбирается более высокий уровень соответствия POSIX (например, самим _POSIX_C_SOURCE, _XOPEN_SOURCE, _DEFAULT_SOURCE или _GNU_SOURCE), то определение не действует _REENTRANT.

    Данный макрос автоматически определяется, если выполняется компиляция cc -pthread.

_THREAD_SAFE
    Синоним (устарел) _REENTRANT, предоставляется для совместимости с некоторыми другими реализациями.

_FORTIFY_SOURCE (начиная с glibc 2.3.4)
    Определение этого макроса вызывает выполнение нескольких простых проверок для обнаружения ошибок переполнения буфера, которые возникают в различных функциях работы со строками и памятью (например, memcpy(3), memset(3), stpcpy(3), strcpy(3), strncpy(3), strcat(3), strncat(3), sprintf(3), snprintf(3), vsprintf(3), vsnprintf(3), gets(3) и их варианты для работы с широкими символами). Для некоторых функций проверяется целостность аргумента; например, проверяется, что open(2) передали в аргументе mode, если указан флаг O_CREAT. Обнаруживаются не все проблемы, только самые распространённые.

    Если значение _FORTIFY_SOURCE равно 1 и уровень оптимизации компиляции равен 1 (gcc -O1) и больше, то выполняются проверки, которые не изменяют поведение выверяемых программ. Если значение _FORTIFY_SOURCE равно 2, то добавляются дополнительные проверки, но некоторые выверяемые программы могут завершаться с ошибкой.

    Некоторые проверки выполняются во время компиляции (через макросы, реализованных в заголовочных файлах) и вызывают предупреждение компилятора; другие проверки выполняются во время выполнения и приводят к ошибкам времени выполнения.

    Для работы этого макроса требуется поддержка в компиляторе, доступная в gcc(1) начиная с версии 4.0.

  Определения по умолчанию, неявные определения и объединяющие определения

Если макросы тестирования свойств не указаны явно, то по умолчанию действуют следующие макросы тестирования свойств: _BSD_SOURCE (в glibc 2.19 и старее), _SVID_SOURCE (в glibc 2.19 и старее), _DEFAULT_SOURCE (начиная с glibc 2.19), _POSIX_SOURCE и _POSIX_C_SOURCE=200809L (200112L в версиях glibc до 2.10; 199506L в версиях glibc до 2.4; 199309L в версиях glibc до 2.1).

Если любой из макросов __STRICT_ANSI__, _ISOC99_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED, _BSD_SOURCE (в glibc 2.19 и старее) или _SVID_SOURCE (в glibc 2.19 и старее) указан явно, то по умолчанию не определяются макросы _BSD_SOURCE, _SVID_SOURCE и _DEFAULT_SOURCE.

Если макросы _POSIX_SOURCE и _POSIX_C_SOURCE не указаны явно и не определён __STRICT_ANSI__ или _XOPEN_SOURCE определён со значением 500 или более, то

*   _POSIX_SOURCE определяется со значением 1; и

*   _POSIX_C_SOURCE определяется с одним из следующих значений:

    •   2, если _XOPEN_SOURCE определён со значением меньше 500;

    •   199506L, если _XOPEN_SOURCE определён со значением 500 или более, но меньше 600; или

    •   (начиная с glibc 2.4) 200112L, если _XOPEN_SOURCE определён со значением 600 или более, но меньше 700.

    •   (начиная с glibc 2.10) 200809L, если _XOPEN_SOURCE определён со значением 700 или более.

    •   Старые версии glibc не знают о значениях 200112L и 200809L у _POSIX_C_SOURCE, и значение этого макроса зависит от версии glibc.

    •   Если макрос _XOPEN_SOURCE не определён, то значение _POSIX_C_SOURCE зависит от версии glibc: 199506L в версиях glibc до 2.4; 200112L в glibc от 2.4 до 2.9 и 200809L в glibc 2.10 и новее.

Можно определять несколько макросов; результат складывается.

СООТВЕТСТВИЕ СТАНДАРТАМ
В POSIX.1 определены _POSIX_C_SOURCE, _POSIX_SOURCE и _XOPEN_SOURCE.

Макрос _XOPEN_SOURCE_EXTENDED был определён в XPG4v2 (также называемом SUSv1), но отсутствует в SUSv2 и более новых версиях. Макрос _FILE_OFFSET_BITS отсутствует в стандартах, но используется в некоторых других реализациях.

Макросы _BSD_SOURCE, _SVID_SOURCE, _DEFAULT_SOURCE, _ATFILE_SOURCE, _GNU_SOURCE, _FORTIFY_SOURCE, _REENTRANT и _THREAD_SAFE есть только в Linux (glibc).

ЗАМЕЧАНИЯ
Файл <features.h> есть только в Linux/glibc. В других системах есть аналогичный файл, но, обычно, с другим именем. Данный заголовочный файл, если нужен, автоматически включается из других заголовочных файлов: его необязательно явно указывать для использования макросов тестирования свойств.

Согласно указанным макросам тестирования свойств раньше файла <features.h>, внутри него определяются другие различные макросы, которые проверяются в других заголовочных файлах glibc. Эти макросы имеют имена, начинающиеся с двух подчёркиваний (например, __USE_MISC). Программы никогда не должны определять эти макросы самостоятельно: вместо этого нужно задействовать соответствующий макрос тестирования свойств из перечисленных ранее.

ПРИМЕР
Представленную далее программу можно использовать для изучения какие значения присваиваются макросам тестирования свойств в зависимости от версии glibc и какие макросы тестирования свойств устанавливаются явно. В следующем сеансе оболочки на системе с glibc 2.10 показаны несколько примеров того, что мы увидели:

    $ cc ftm.c
    $ ./a.out
    _POSIX_SOURCE defined
    _POSIX_C_SOURCE defined: 200809L
    _BSD_SOURCE defined
    _SVID_SOURCE defined
    _ATFILE_SOURCE defined
    $ cc -D_XOPEN_SOURCE=500 ftm.c
    $ ./a.out
    _POSIX_SOURCE defined
    _POSIX_C_SOURCE defined: 199506L
    _XOPEN_SOURCE defined: 500
    $ cc -D_GNU_SOURCE ftm.c
    $ ./a.out
    _POSIX_SOURCE defined
    _POSIX_C_SOURCE defined: 200809L
    _ISOC99_SOURCE defined
    _XOPEN_SOURCE defined: 700
    _XOPEN_SOURCE_EXTENDED defined
    _LARGEFILE64_SOURCE defined
    _BSD_SOURCE defined
    _SVID_SOURCE defined
    _ATFILE_SOURCE defined
    _GNU_SOURCE defined

  Исходный код программы
    /* ftm.c */
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    int
    main(int argc, char *argv[])
    {
    #ifdef _POSIX_SOURCE
        printf("_POSIX_SOURCE defined\n");
    #endif
    #ifdef _POSIX_C_SOURCE
        printf("_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
    #endif
    #ifdef _ISOC99_SOURCE
        printf("_ISOC99_SOURCE defined\n");
    #endif
    #ifdef _ISOC11_SOURCE
        printf("_ISOC11_SOURCE defined\n");
    #endif
    #ifdef _XOPEN_SOURCE
        printf("_XOPEN_SOURCE defined: %d\n", _XOPEN_SOURCE);
    #endif
    #ifdef _XOPEN_SOURCE_EXTENDED
        printf("_XOPEN_SOURCE_EXTENDED defined\n");
    #endif
    #ifdef _LARGEFILE64_SOURCE
        printf("_LARGEFILE64_SOURCE defined\n");
    #endif
    #ifdef _FILE_OFFSET_BITS
        printf("_FILE_OFFSET_BITS defined: %d\n", _FILE_OFFSET_BITS);
    #endif
    #ifdef _BSD_SOURCE
        printf("_BSD_SOURCE defined\n");
    #endif
    #ifdef _SVID_SOURCE
        printf("_SVID_SOURCE defined\n");
    #endif
    #ifdef _DEFAULT_SOURCE
        printf("_DEFAULT_SOURCE defined\n");
    #endif
    #ifdef _ATFILE_SOURCE
        printf("_ATFILE_SOURCE defined\n");
    #endif
    #ifdef _GNU_SOURCE
        printf("_GNU_SOURCE defined\n");
    #endif
    #ifdef _REENTRANT
        printf("_REENTRANT defined\n");
    #endif
    #ifdef _THREAD_SAFE
        printf("_THREAD_SAFE defined\n");
    #endif
    #ifdef _FORTIFY_SOURCE
        printf("_FORTIFY_SOURCE defined\n");
    #endif
        exit(EXIT_SUCCESS);
    }

СМОТРИТЕ ТАКЖЕ
libc(7), standards(7)

Раздел «Макросы тестирования свойств» в info libc.

/usr/include/features.h