Почему люди так часто используют __(двойное подчеркивание) в C++
Я просматривал некоторый код C++ с открытым исходным кодом и заметил, что в коде много двойных недооценок, в основном в начале имен переменных.
return __CYGWIN__;
Просто интересно, есть ли причина для этого, или это просто некоторые стили кода людей? Я думаю, что мне трудно читать.
6 ответов
Из программирования на C++, правила и рекомендации:
Использование двух подчеркиваний (`__') в идентификаторах зарезервировано для внутреннего использования компилятором в соответствии со стандартом ANSI-C.
Символы подчеркивания (`_') часто используются в именах библиотечных функций (таких как" _main "и"_exit"). Чтобы избежать коллизий, не начинайте идентификатор с подчеркивания.
Если они не чувствуют, что являются "частью реализации", то есть стандартными библиотеками, они не должны этого делать.
Правила довольно специфичны и немного более подробны, чем предлагали некоторые другие.
Все идентификаторы, которые содержат двойное подчеркивание или начинаются с подчеркивания, за которым следует заглавная буква, зарезервированы для использования реализацией во всех областях, то есть они могут использоваться для макросов.
Кроме того, все другие идентификаторы, которые начинаются со знака подчеркивания (то есть за ним не следует другое подчеркивание или заглавная буква), зарезервированы для реализации в глобальной области видимости. Это означает, что вы можете использовать эти идентификаторы в ваших собственных пространствах имен или в определениях классов.
Вот почему Microsoft использует имена функций с начальным подчеркиванием и строчными буквами для многих из своих основных функций библиотеки времени выполнения, которые не являются частью стандарта C++. Эти имена функций гарантированно не конфликтуют ни со стандартными функциями C++, ни с функциями пользовательского кода.
Согласно стандарту C++ идентификаторы, начинающиеся с одного подчеркивания, зарезервированы для библиотек. Идентификаторы, начинающиеся с двух подчеркиваний, зарезервированы для поставщиков компиляторов.
Самый популярный ответ цитирует Программирование на C++: правила и рекомендации:
"Использование двух подчеркиваний (`__') в идентификаторах зарезервировано для внутреннего использования компилятором в соответствии со стандартом ANSI-C ".
Тем не менее, утверждение этой страницы кажется необоснованным
Я искал несколько стандартов C++ и C и не смог найти упоминаний о подчеркиваниях, ограниченных внутренним использованием компилятора.
C++ (текущий рабочий проект, доступ 2019-5-26) говорится в lex.name
:
- Каждый идентификатор, который содержит двойное подчеркивание __ или начинается с подчеркивания, за которым следует заглавная буква, зарезервирован для реализации для любого использования.
- Каждый идентификатор, который начинается со знака подчеркивания, зарезервирован для реализации для использования в качестве имени в глобальном пространстве имен.
TL; DR: двойные подчеркивания зарезервированы для реализации
Хотя этот вопрос специфичен для C++, я привел соответствующие разделы из стандартов C 99 и 17:
C99 раздел 7.1.3
- Все идентификаторы, которые начинаются со знака подчеркивания, а также заглавной буквы или другого подчеркивания, всегда зарезервированы для любого использования.
- Все идентификаторы, которые начинаются с подчеркивания, всегда зарезервированы для использования в качестве идентификаторов с областью действия файла как в обычном пространстве, так и в пространстве имен тега.
С17 говорит то же самое, что и С99.
Приведенные выше комментарии являются правильными. __Symbol__
обычно это магический токен, предоставляемый вашим полезным поставщиком компиляторов (или препроцессоров). Возможно, наиболее широко используемые из них __FILE__
а также __LINE__
, которые расширяются препроцессором C для указания текущего имени файла и номера строки. Это удобно, когда вы хотите регистрировать какой-либо сбой утверждения программы, включая текстовое расположение ошибки.
Это то, что вы не должны делать в "нормальном" коде. Это гарантирует, что компиляторы и системные библиотеки могут определять символы, которые не будут конфликтовать с вашими.
В дополнение к библиотекам, о которых ответили многие другие, некоторые люди также называют макросы или значения #define для использования с препроцессором. Это облегчило бы работу и, возможно, позволило бы обойти ошибки в старых компиляторах.
Как и другие упомянутые, это помогает предотвратить конфликт имен и помогает разграничить переменные библиотеки и ваши собственные.