Выбрать главу

• _GNU_SOURCE — если он задан (с любым значением), то предоставляет все определения, предусмотренные предыдущими макросами, а также определения различных GNU-расширений.

Когда компилятор GNU C вызывается без специальных ключей, то по умолчанию определяются _POSIX_SOURCE, _POSIX_C_SOURCE=200809 (200112 с glibc версий от 2.5 до 2.9 или 199506 с glibc версии ниже 2.4), _BSD_SOURCE и _SVID_SOURCE.

Если определены отдельные макросы или компилятор вызван в одном из стандартных режимов (например, cc — ansi или cc — std=c99), то предоставляются только запрошенные определения. Существует одно исключение: если _POSIX_C_SOURCE не задан каким-либо другим образом и компилятор не вызван в одном из стандартных режимов, то _POSIX_C_SOURCE определяется со значением 200809 (200112 с glibc версий от 2.4 до 2.9 или 199506 с glibc версии ниже 2.4).

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

$ cc — D_POSIX_SOURCE — D_POSIX_C_SOURCE=199506 \

— D_BSD_SOURCE — D_SVID_SOURCE prog.c

Дополнительную информацию, уточняющую значения, присваиваемые каждому макросу проверки возможностей, можно найти в заголовочном файле <features.h> и на странице руководства feature_test_macros(7).

_POSIX_C_SOURCE, _XOPEN_SOURCE и POSIX.1/SUS

В POSIX.1-2001/SUSv3 указаны только макросы проверки возможностей _POSIX_C_SOURCE и _XOPEN_SOURCE с требованием, чтобы в соответствующих приложениях они были определены со значениями 200112 и 600. Определение _POSIX_C_SOURCE со значением 200112 обеспечивает соответствие базовой спецификации POSIX.1-2001 (то есть соответствие POSIX, исключая XSI-расширение). Определение _XOPEN_SOURCE со значением 600 обеспечивает соответствие спецификации SUSv3 (то есть соответствие XSI — базовой спецификации плюс XSI-расширению). То же самое относится к POSIX.1-2008/SUSv4 с требованием, чтобы два макроса были определены со значениями 200809 и 700.

В SUSv3 указывается, что установка для _XOPEN_SOURCE значения 600 должна предоставлять все свойства, включаемые, если _POSIX_C_SOURCE присвоено значение 200112. Таким образом, для соответствия SUSv3 (то есть XSI) приложению необходимо определить только _XOPEN_SOURCE. В SUSv4 делается аналогичное требование: установка для _XOPEN_SOURCE значения 700 должна предоставлять все свойства, включаемые, если _POSIX_C_SOURCE присвоено значение 200809.

Макросы проверки возможностей в прототипах функций и в исходном коде примеров

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

Все примеры исходного кода в этой книге написаны таким образом, чтобы их можно было скомпилировать, используя либо настройки по умолчанию компилятора GNU C, либо следующие ключи:

$ cc — std=c99 — D_XOPEN_SOURCE=600

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

3.6.2. Типы системных данных

При использовании стандартных типов языка C вам предоставляются различные типы данных реализации, например идентификаторы процессов, идентификаторы пользователей и смещения в файлах. Конечно, для объявления переменных, хранящих подобную информацию, можно было бы использовать основные типы языка C, например int и long, но это сокращает возможность портирования между системами UNIX по следующим причинам.

• Размеры этих основных типов от реализации к реализации UNIX отличаются друг от друга (например, long в одной системе может занимать 4 байта, а в другой — 8 байт). Иногда отличия могут прослеживаться даже в разных средах компиляции одной и той же реализации. Кроме того, в разных реализациях для представления одной и той же информации могут использоваться различные типы. Например, в одной системе идентификатор процесса может быть типа int, а в другой — типа long.

• Даже в одной и той же реализации UNIX типы, используемые для представления информации, могут в разных выпусках отличаться друг от друга. Наглядными примерами в Linux могут послужить идентификаторы пользователей и групп. В Linux 2.2 и более ранних версиях эти значения были представлены в 16 разрядах. В Linux 2.4 более поздних версиях они представлены в виде 32-разрядных значений.

Чтобы избежать подобных проблем портирования, в SUSv3 указываются различные стандартные типы системных данных, а к реализации предъявляются требования по надлежащему определению и использованию этих типов.