Может ли реализация, совместимая с ANSI C, включать дополнительные функции в свою стандартную библиотеку?

Разрешено ли ANSI C-совместимой реализации включать в свою стандартную библиотеку дополнительные типы и функции, помимо перечисленных в стандарте? (Идеальный ответ - ссылка на соответствующую часть стандарта ANSI.)

Я спрашиваю, в частности, потому что Mac OS 10.7 объявляет функцию getline в stdio.h даже при компиляции с помощью gcc или clang с использованием флага -ansi. Это нарушает работу нескольких старых программ, которые определяют свои собственные getline функции. Это ошибка Mac OS 10.7? (На странице руководства для 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?


person Brad Larsen    schedule 11.09.2011    source источник


Ответы (2)


Из раздела 7.1.3 абзаца 2 документа n1570 (который является черновиком C1x):

Никакие другие идентификаторы не зарезервированы.

Это часть, которая означает, что getline не должен определяться <stdio.h>, поскольку это не зарезервированный идентификатор в соответствии со спецификацией. Итак, если ваша библиотека определяет getline в <stdio.h>, это технически несовместимо со стандартом C ...

Однако вы должны иметь возможность использовать макросы тестирования функций, чтобы getline не было определено в <stdio.h>.

#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>

Это даст вам только определения из старых стандартов POSIX. Это не будет работать для некоторых реализаций GNU C ++, что для некоторых является ВНЕШНИМ ПРИНЦИПОМ.

Соответствующий раздел справочной страницы (взят из справочной страницы glibc, извините ...)

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       getline(), getdelim():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
           Before glibc 2.10:
               _GNU_SOURCE

Эта часть справочной страницы сообщает вам, какие макросы должны быть определены для каких значений, чтобы получить определение. Держу пари, что _POSIX_C_SOURCE уже определен вашим компилятором для 200809L.

Идея макросов тестирования функций заключается в том, что если вы определяете свои макросы, такие как _POSIX_C_SOURCE, _BSD_SOURCE, _XOPEN_SOURCE и т. Д., С желаемыми значениями, вам не нужно будет беспокоиться о конфликте новых библиотечных функций с вашими существующими функциями. Также есть _GNU_SOURCE, который включает все, если вы используете glibc, но я предлагаю не использовать этот макрос.

person Dietrich Epp    schedule 11.09.2011
comment
Ваш ответ позволил мне снова скомпилировать код ANSI C89 путем определения _POSIX_C_SOURCE 1. (Это значение должно включать только функции ANSI C89 / ISO C90.) Эти макросы тестирования функций не задокументированы на странице руководства Mac для getline, а страница руководства feature_test_macros не существует на Mac. Я бы их не нашел без вашего ответа. Хотя ваш ответ сейчас не отвечает на мой исходный вопрос (является ли реализация ANSI C разрешенной для объявления других функций в своей стандартной библиотеке), ваш ответ касается моей реальной проблемы. Я бы проголосовал дважды, если бы мог! - person Brad Larsen; 11.09.2011
comment
Часть стандарта, в которой говорится, что другие идентификаторы не зарезервированы, означает, что реализации технически не разрешено определять другие функции в своих заголовках, но я не совсем понял это. - person Dietrich Epp; 11.09.2011

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

  • Все идентификаторы, начинающиеся с символа подчеркивания и заглавной буквы или другого символа подчеркивания, всегда зарезервированы для любого использования;

  • Все идентификаторы, начинающиеся с подчеркивания, всегда зарезервированы для использования в качестве идентификаторов с областью файлов как в обычном пространстве имен, так и в пространстве имен тегов;

  • Все внешние имена, начинающиеся с is, to, str, mem или wcs, за которыми следует строчная буква;

Кроме того, есть имена, которые зарезервированы только в том случае, если вы включаете определенные заголовки; например, если вы включаете <errno.h>, он может определять любой макрос, начинающийся с E, за которым следует цифра или заглавная буква.

Однако getline() не такое зарезервированное имя, и соответствующая реализация должна сделать его доступным для собственного использования программистом.

person caf    schedule 11.09.2011
comment
Это почти ответ, который я ищу. Есть ли у вас ссылка, которая оправдывает ваше заявление о том, что getline() должен быть доступен для собственного использования программистом? - person Brad Larsen; 11.09.2011
comment
@Bradford Larsen: стандарт C (N1256 является последним стандартом C99, обновленным TC1, TC2 и TC3). В частности, см. Разделы 7.1.3 и 7.26. - person caf; 12.09.2011