Является ли реализация, совместимая с ANSI C, разрешенной включать дополнительные типы и функции в свою стандартную библиотеку, помимо тех, которые перечислены стандартом? (Идеальный ответ будет ссылаться на соответствующую часть стандарта ANSI).
Я спрашиваю, особенно потому, что Mac OS 10.7 объявляет функцию getline
в stdio.h, даже при компиляции с gcc или clang с использованием флага -ansi
. Это разбивает несколько старых программ, которые определяют их собственную функцию getline
. Это ошибка Mac OS 10.7? (На странице man для getline
на Mac OS 10.7 говорится, что getline
соответствует стандарту POSIX.1, который появился в 2008 году).
Изменить: для пояснения мне кажется странным, что включение stdio.h в программу ANSI C89 в Mac OS 10.7 также втягивает объявление для функции getline
, поскольку getline
не является одной из функций, перечисленных в K & R (и предположительно ANSI) описание stdio.h. В частности, попытка компиляции noweb :
gcc -ansi -pedantic -c -o notangle.o notangle.c In file included from notangle.nw:28: getline.h:4: error: conflicting types for 'getline' /usr/include/stdio.h:449: error: previous declaration of 'getline' was here
Это ошибка в Mac OS 10.7 включает объявление getline
в stdio.h, даже при компиляции для стандарта ANSI C89?
Из раздела 7.1.3 параграфа 2 n1570 (который представляет собой проект C1x):
Никакие другие идентификаторы не зарезервированы.
Это часть, которая означает, что getline
не следует определять с помощью
, поскольку она не является зарезервированным идентификатором в соответствии со спецификацией. Поэтому, если ваша библиотека определяет getline
в
, она технически не совместима со стандартом C …
Тем не менее, вы должны иметь возможность использовать macros проверки функций, чтобы заставить getline
быть неопределенным в
.
#undef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200112L #include
Это даст вам только определения из старых стандартов POSIX. Это не сработает для некоторых реализаций GNU C ++, которые для некоторых людей являются ExTrEmeLY fruSTRaTiNG .
Соответствующий раздел manpage (взято из man-страницы glibc, извините …)
Требования к макросам проверки свойств для glibc (см. Feature_test_macros (7)): getline (), getdelim (): Поскольку glibc 2.10: _POSIX_C_SOURCE> = 200809L || _XOPEN_SOURCE> = 700 До glibc 2.10: _GNU_SOURCE
Эта часть manpage сообщает вам, какие macros должны быть определены для каких значений, чтобы получить определение. Моя ставка заключается в том, что _POSIX_C_SOURCE
уже определен вашим компилятором до 200809L
.
Идея макросов проверки функций заключается в том, что если вы определяете свои macros, такие как _POSIX_C_SOURCE
, _BSD_SOURCE
, _XOPEN_SOURCE
и т. Д. Для значений, которые вы хотите, вам не нужно беспокоиться о новых функциях библиотеки, связанных с вашими существующими функциями. Существует также _GNU_SOURCE
, который включает все, если вы используете glibc, но я предлагаю предоставить этот макрос широкий причал.
Да, совместимой реализации разрешено определять дополнительные идентификаторы, включая функции, если они являются одним из зарезервированных идентификаторов в стандарте. Например:
Все идентификаторы, начинающиеся с символа подчеркивания и либо заглавная буква, либо под другим символом подчеркивания, всегда зарезервированы для любого использования;
Все идентификаторы, начинающиеся с подчеркивания, всегда зарезервированы для использования в качестве идентификаторов с областью файлов как в обычном, так и в имени тегов;
Все внешние имена, начинающиеся с is
to
, str
, mem
или wcs
сопровождаются строчной буквой;
Кроме того, есть имена, зарезервированные только в том случае, если вы включаете определенные заголовки; например, если вы включили
тогда он может определить любой макрос, начинающийся с E
за которым следует цифра или буква верхнего регистра.
Однако getline()
не является таким зарезервированным именем, и совместимая реализация должна сделать его доступным для собственного использования программистом.