Ответ 1
Правила (которые не изменились в C++ 11):
- Зарезервировано в любой области, в том числе для использования в качестве макросов реализации:
- идентификаторы, начинающиеся со знака подчеркивания, за которыми сразу следует заглавная буква
- идентификаторы, содержащие соседние подчеркивания (или "двойное подчеркивание")
- Зарезервировано в глобальном пространстве имен:
- идентификаторы, начинающиеся с подчеркивания
- Кроме того, все в пространстве имен
std
зарезервировано. (Вы можете добавить шаблонные специализации, хотя.)
Из стандарта 2003 C++:
17.4.3.1.2 Глобальные имена [lib.global.names]
Определенные наборы имен и сигнатур функций всегда зарезервированы для реализации:
- Каждое имя, которое содержит двойное подчеркивание (
__
) или начинается с подчеркивания, за которым следует заглавная буква (2.11), зарезервировано для реализации для любого использования.- Каждое имя, которое начинается со знака подчеркивания, зарезервировано для реализации для использования в качестве имени в глобальном пространстве имен. 165
165) Такие имена также зарезервированы в пространстве имен
::std
(17.4.3.1).
Поскольку C++ основан на стандарте C (1.1/2, C++ 03), а C99 является нормативным справочным документом (1.2/1, C++ 03), они также применяются в стандарте C 1999 года:
7.1.3 Зарезервированные идентификаторы
Каждый заголовок объявляет или определяет все идентификаторы, перечисленные в связанном с ним подпункте, и, необязательно, объявляет или определяет идентификаторы, перечисленные в соответствующем подпункте будущих направлений библиотеки, и идентификаторы, которые всегда зарезервированы либо для любого использования, либо для использования в качестве идентификаторов области файла.
- Все идентификаторы, которые начинаются со знака подчеркивания, а также заглавной буквы или другого знака подчеркивания, всегда зарезервированы для любого использования.
- Все идентификаторы, которые начинаются с подчеркивания, всегда зарезервированы для использования в качестве идентификаторов с областью действия файла как в обычном пространстве, так и в пространстве имен тега.
- Каждое имя макроса в любом из следующих подпунктов (включая будущие направления библиотеки) зарезервировано для использования, как указано, если включен какой-либо из связанных с ним заголовков; если прямо не указано иное (см. 7.1.4).
- Все идентификаторы с внешней связью в любом из следующих подпунктов (включая будущие направления библиотеки) всегда зарезервированы для использования в качестве идентификаторов с внешней связью. 154
- Каждый идентификатор с областью файла, указанной в любом из следующих подпунктов (включая будущие направления библиотеки), зарезервирован для использования в качестве имени макроса и в качестве идентификатора с областью файла в том же пространстве имен, если включен какой-либо из связанных с ним заголовков.
Другие идентификаторы не зарезервированы. Если программа объявляет или определяет идентификатор в контексте, в котором она зарезервирована (за исключением случаев, разрешенных в 7.1.4), или определяет зарезервированный идентификатор как имя макроса, поведение не определено.
Если программа удаляет (с помощью
#undef
) любое макроопределение идентификатора в первой группе, указанной выше, поведение не определено.154) Список зарезервированных идентификаторов с внешней связью включает в себя
errno
,math_errhandling
,setjmp
иva_end
.
Другие ограничения могут применяться. Например, стандарт POSIX резервирует множество идентификаторов, которые могут отображаться в обычном коде:
- Имена, начинающиеся с заглавной буквы
E
после цифры или заглавной буквы:- может использоваться для дополнительных имен кодов ошибок.
- Имена, начинающиеся с
is
илиto
за которыми следует строчная буква- может использоваться для дополнительного тестирования символов и функций преобразования.
- Имена, которые начинаются с
LC_
за которым следует заглавная буква- может использоваться для дополнительных макросов, определяющих атрибуты локали.
- Имена всех существующих математических функций с суффиксом
f
илиl
зарезервированы- для соответствующих функций, которые работают с плавающими и длинными двойными аргументами, соответственно.
- Имена, которые начинаются с
SIG
за которым следует заглавная буква, зарезервированы- для дополнительных имен сигналов.
- Имена, которые начинаются с
SIG_
за которым следует заглавная буква, зарезервированы- для дополнительных сигнальных действий.
- Имена, начинающиеся с
str
,mem
илиwcs
за которыми следует строчная буква, зарезервированы- для дополнительных строковых и массивных функций.
- Имена, начинающиеся с
PRI
илиSCN
за которыми следует любая строчная буква илиX
, зарезервированы- для дополнительных макросов спецификатора формата
- Имена, заканчивающиеся на
_t
, зарезервированы- для дополнительных имен типов.
Хотя использование этих имен в ваших собственных целях в настоящее время может не вызывать проблем, они повышают вероятность конфликта с будущими версиями этого стандарта.
Лично я просто не начинаю идентификаторы с подчеркивания. Новое дополнение к моему правилу: нигде не используйте двойные подчеркивания, что легко, так как я редко использую подчеркивание.
После исследования этой статьи я больше не заканчиваю свои идентификаторы _t
поскольку это зарезервировано стандартом POSIX.
Правило о любом идентификаторе, оканчивающемся на _t
меня очень удивило. Я думаю, что это стандарт POSIX (пока не уверен), требующий пояснений, официальных главы и стиха. Это из руководства по GNU libtool, в котором перечислены зарезервированные имена.
CesarB предоставил следующую ссылку на зарезервированные символы POSIX 2004 и отмечает, что "там можно найти много других зарезервированных префиксов и суффиксов...". Зарезервированные символы POSIX 2008 определены здесь. Ограничения несколько более нюансированы, чем указанные выше.