Зарезервированные имена в глобальном пространстве имен

Исходя из моего ответа на Динамический массив объектов в C++ и в качестве продолжения на Что такое правила о использовать подчеркивание в идентификаторе C++?: видимо, имена, начинающиеся с _, за которыми следует заглавная буква, зарезервированы в глобальном пространстве имен.

17.4.3.2.1 Глобальные имена [lib.global.names]

Определенные наборы имен и сигнатур функций всегда зарезервированы для реализации:

  • Каждое имя, которое содержит двойное подчеркивание (__) или начинается с подчеркивания, за которым следует заглавная буква (2.11), зарезервировано реализацией для любого использования.
  • Каждое имя, начинающееся со знака подчеркивания, зарезервировано реализацией для использования в качестве имени в глобальном пространстве имен.165

165) Такие имена также зарезервированы в пространстве имен ::std (17.4.3.1).

В моем ответе на первый вопрос у меня был класс, который выглядел так

class A
{
 private:
   vector<int> _Ints;
}

В комментариях мне сказали, что идентификатор _Ints вызывает неопределенное поведение, поскольку это зарезервированное имя. Однако, согласно последнему проекту стандарта, поиск имени переменной-члена происходит по следующему правилу:

3.4.3.1 Члены класса [class.qual]

Если вложенный-спецификатор-имени для квалифицированного-идентификатора назначает класс, имя, указанное после вложенного-имени-спецификатора, ищется в область применения класса (10.2), за исключением случаев, перечисленных ниже. Имя должно представлять одного или нескольких членов этого класса или одного из его базовых классов.

Для меня это означает, что никакая переменная-член никогда не может быть частью глобального пространства имен, поскольку ее областью действия является класс.

А теперь вопрос:

Правильно ли я понимаю, что переменные-члены никогда не будут нарушать правило зарезервированных имен реализации, поскольку они не находятся в глобальном пространстве имен? Если я не прав, может ли кто-нибудь объяснить мое непонимание правила поиска?


person rerun    schedule 12.03.2012    source источник


Ответы (3)


_Int явно нарушает первое правило: каждое имя, которое содержит двойное подчеркивание (_ _) или начинается с подчеркивания, за которым следует заглавная буква (2.11), зарезервировано реализацией для любого использования. любое использование означает именно то, что оно говорит: это может быть предопределенный макрос, или запускать какое-то особое поведение в компиляторе, или что-то еще, что хочет автор компилятора. Неважно, где вы используете имя, если вы его используете, это неопределенное поведение (если в документации компилятора не указано иное).

В более общем плане, по крайней мере исторически, компиляторы были довольно слабыми, и ряд системных заголовков традиционно включал макросы с именами, начинающимися с одного подчеркивания, за которым следует строчная буква. Вероятно, лучше избегать и их. (Исторически даже были имена без подчеркивания. Я знаю, что у меня были проблемы с тем, что имя linux становилось 1. Никаких подчеркиваний не видно, но... Однако с этим мало что можно сделать, кроме изменить имя при возникновении конфликта.)

В более общем случае подчеркивания не так хорошо отображаются в некоторых шрифтах, и лучше избегать их на обоих концах символа.

person James Kanze    schedule 12.03.2012
comment
символы подчеркивания не так хорошо отображаются в некоторых шрифтах - 1, l и I выглядят одинаково в некоторых шрифтах, поэтому избегайте их в идентификаторах? Или избегать этих шрифтов при чтении кода? - person Steve Jessop; 12.03.2012
comment
Я согласен со Стивом, символы подчеркивания — это факт жизни в программировании, если ваш шрифт не может их отобразить, у вас проблемы. (Я использую пропорциональные шрифты и до сих пор не имею проблем) - person edA-qa mort-ora-y; 12.03.2012
comment
Однако я довольно экстремально настроен в этом отношении - если я могу этого избежать, я не читаю код в шрифте (или, во всяком случае, в настройках текстового редактора), который не различает символ табуляции и эквивалентное количество пробелов. Так что у меня довольно высокие стандарты базовой читаемости текста. - person Steve Jessop; 12.03.2012
comment
@SteveJessop Иметь символы, которые отличаются только тем, что в одном используется строчная буква l, а в другом цифра 1, не очень хорошая идея. Что касается подчеркивания, то оно разделяет слова (где тот факт, что они напоминают пробел, не является большой проблемой), но различать _name, name_ и name едва ли лучше, чем использовать x1, xl или xO и x0. - person James Kanze; 12.03.2012

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

Идентификаторы, начинающиеся со знака подчеркивания, за которым не следует знак подчеркивания или заглавная буква, зарезервированы в глобальном пространстве имен. Таким образом, вам разрешено называть переменную-член, например, _ints, но вы не можете иметь глобальную переменную с именем _ints, которая находится в глобальном пространстве имен.

person interjay    schedule 12.03.2012
comment
Я использовал использование для обозначения любой цели, а не любого масштаба. почему это правило находится в разделе глобальных имен. - person rerun; 12.03.2012
comment
@rerun Конечно, любая цель включает в себя объявление переменной в любой области. Название раздела сбивает с толку, но важен текст раздела, который четко разделяет зарезервированные идентификаторы на два типа: зарезервированные для любого использования и зарезервированные в глобальном пространстве имен. - person interjay; 12.03.2012

по-видимому, _ (заглавная буква) зарезервировано в глобальном пространстве имен.

Нет. Он зарезервирован везде. Прочтите 17.4.3.2.1 еще раз:

Каждое имя, которое содержит двойное подчеркивание (_ _) или начинается с подчеркивания, за которым следует заглавная буква (2.11), зарезервировано реализацией для любого использования.

Здесь вообще не упоминается «глобальное пространство имен» (глобальное пространство имен имеет значение только в последующем правиле).

person Konrad Rudolph    schedule 12.03.2012