Ответ 1
В C для реализации сохраняются символы, начинающиеся с символа подчеркивания, за которым следует либо верхняя буква, либо другое подчеркивание. Вы, как пользователь C, не должны создавать символы, начинающиеся с зарезервированных последовательностей. В С++ ограничение является более строгим; вы не можете создать символ, содержащий двойной знак подчеркивания.
Дано:
extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
__THROW;
Обозначение __const
позволяет предположить (несколько маловероятно), что компилятор использует этот код для поддержки прототипов нотации, но не имеет правильного понимания стандартного ключевого слова C89 const
. Макросы autoconf
все еще могут проверить, поддерживает ли компилятор поддержку const
; этот код можно использовать со сломанным компилятором, который не имеет такой поддержки.
Использование __hostname
и __addr
- это мера защиты для вас, пользователя заголовка. Если вы скомпилируете GCC и параметр -Wshadow
, компилятор предупредит вас, когда какие-либо локальные переменные будут затенять глобальную переменную. Если функция использовала только hostname
вместо __hostname
, и если бы у вас была функция с именем hostname()
, было бы затенение. Используя имена, зарезервированные для реализации, нет конфликта с вашим законным кодом.
Использование __THROW
означает, что код может при определенных обстоятельствах быть объявлен с какой-то "спецификацией броска". Это не стандарт C; это больше похоже на С++. Но код может использоваться с компилятором C, если один из заголовков (или сам компилятор) определяет __THROW
для пустого или для некоторого расширения, специфичного для компилятора стандартного синтаксиса C.
В разделе 7.1.3 стандарта C (ISO 9899: 1999) говорится:
7.1.3 Зарезервированные идентификаторы
Каждый заголовок объявляет или определяет все идентификаторы, перечисленные в соответствующем подпункте, и необязательно объявляет или определяет идентификаторы, перечисленные в связанных им будущих направлениях библиотеки подпунктом и идентификаторами, которые всегда зарезервированы либо для любого использования, либо для использования в качестве файла идентификаторы областей.
- все идентификаторы, начинающиеся с символа подчеркивания, и либо прописная буква, либо другая underscore всегда зарезервированы для любого использования.
- Все идентификаторы, начинающиеся с символа подчеркивания, всегда зарезервированы для использования в качестве идентификаторов с объемом файла как в обычном, так и в имени тегов.
- Каждое имя макроса в любом из следующих подпунктов (включая будущую библиотеку направления) зарезервировано для использования, как указано, если включен какой-либо из его связанных заголовков; если явно не указано иное (см. 7.1.4).
- Все идентификаторы с внешней связью в любом из следующих подпунктов (включая будущие направления библиотек) всегда зарезервированы для использования в качестве идентификаторов с внешними связь. 154)
- Каждый идентификатор с областью файлов, указанный в любом из следующих подпунктов (включая будущие направления библиотек) зарезервирован для использования в качестве имени макроса и в качестве идентификатора с область файла в том же пространстве имен, если включен какой-либо из связанных заголовков.
Никакие другие идентификаторы не зарезервированы. Если программа объявляет или определяет идентификатор в контекст, в котором он зарезервирован (кроме как разрешено в соответствии с пунктом 7.1.4), или определяет зарезервированный идентификатор в качестве имени макроса, поведение undefined.
Если программа удаляет (с
#undef
) любое определение макроса идентификатора в первом группа, указанная выше, поведение undefined.Сноска 154) Список зарезервированных идентификаторов с внешней привязкой включает
errno
,math_errhandling
,setjmp
иva_end
.
См. также Каковы правила использования подчеркивания в идентификаторе на С++; многие одинаковые правила применяются как к C, так и к С++, хотя встроенное правило двойного подчеркивания находится только на С++, как указано в начале этого ответа.