ИМЯ feature_test_macros - макросы тестирования свойств
ОПИСАНИЕ Макросы тестирования свойств позволяют программисту контролировать какие определения будут доступны из системных заголовочных файлов при компиляции программы.
ЗАМЕЧАНИЕ: В целях эффективности, макрос тестирования свойств должен быть определён до включения всех заголовочных файлов. Это можно сделать или в команде компиляции (cc -DМАКРОС=значение) или определив макрос в исходном коде до включения заголовочных файлов.
Некоторые макросы тестирования свойств полезны для создания переносимых приложений; они позволяют блокировать нестандартные определения. Другие макросы можно использовать для разблокировки нестандартных определений, которые по умолчанию недоступны.
Действие каждого макроса тестирования свойств, описанного далее, можно узнать из содержимого заголовочного файла <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>
Если кратко:
* Макросы, которые вам, вероятно, понадобится использовать в современном коде: _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_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, последний (устаревший) макрос совместимости.
Делает доступными определения стандарта 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 в случае конфликта приоритета не имеют.
_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. Определение этого макроса вызывает выполнение нескольких простых проверок для обнаружения ошибок переполнения буфера, которые возникают в различных функциях работы со строками и памятью (например, 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_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> #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 Раздел «Макросы тестирования свойств» в info libc.
/usr/include/features.h
|