Менталитет префикса GNU _M_

Если мы посмотрим на реализацию GNU libstdc++, я заметил, что в реализациях стандартных классов частные функции-члены различных классов имеют префикс _M_. Например, у std::basic_string<> среди прочих есть член по имени bool _M_is_shared() const;.

Я понимаю мотивацию иметь какое-то соглашение об именах для частных переменных-членов. Это помогает визуально различать члены класса и локальные переменные функции. Но я не понимаю, почему префикс _M_ предпочтительнее для закрытых функций-членов.

Если я вижу какой-то код, который вызывает, например: is_shared();, по сути, есть только несколько вариантов:

  1. это функция-член этого класса
  2. это функция-член родительского класса
  3. это глобальная функция.

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

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


person Evan Teran    schedule 21.03.2014    source источник
comment
возможный дубликат Почему соглашение об именах STL используют так много подчеркивания в начале?. Это та же проблема, в библиотеке GNU C++ мы используем __foo для локальных переменных и аргументов и _M_foo или _S_foo для членов, но в обоих случаях мы должны использовать зарезервированные имена, чтобы гарантировать, что мы не конфликтуем с какими-либо макросами, определенными пользователями.   -  person Jonathan Wakely    schedule 25.03.2014


Ответы (2)


Идентификаторы, начинающиеся со знака подчеркивания, а затем с заглавной буквы или начинающиеся с двух знаков подчеркивания, «зарезервированы для реализации во всех контекстах».

Это означает, что в соответствии со Стандартом чья-либо программа будет незаконна #define _M_is_shared false и нарушить заголовочный файл библиотеки. Если бы они использовали более обычные идентификаторы, риск такого конфликта имен в других действительных программах был бы выше.

person aschepler    schedule 21.03.2014
comment
ах! Я не думал о том, что кто-то использует макрос, чтобы переопределить что-то приватное в заголовке... зло :-P - person Evan Teran; 21.03.2014
comment
Я не знаю, зло ли это ... несмотря на то, что вы зарезервированы, вы все равно можете скомпилировать код, который соблюдает все зарезервированные соглашения об именах (которые вы в основном должны разрешить, если люди собираются менять реализации). Зарезервированные имена служат для большей безопасности, но не мешают никому что-либо делать. - person IdeaHat; 21.03.2014
comment
@MadScienceDreams: 17.6.4.3/2: если программа объявляет или определяет имя в контексте, в котором оно зарезервировано, за исключением случаев, явно разрешенных этим пунктом, ее поведение не определено. Да, вы можете это сделать, но стандарт указывает, что это так же плохо, как разыменование nullptr, и все, что идет не так, является ошибкой программы, а не реализации. - person aschepler; 21.03.2014
comment
@aschepler Извините, не пытался критиковать, вы совершенно правы. Это УЖАСНАЯ идея, чтобы попытаться возиться с реализацией. Я просто указал, что это разрешено, и что единственная причина, по которой вы когда-либо делали это, - это изменение реализации библиотеки. - person IdeaHat; 21.03.2014
comment
@MadScienceDreams, нет это не разрешено! Иногда это возможно, потому что препроцессор глуп и не останавливает вас, но если ваша программа сломается, вы сохраните обе части. И соответствующая реализация может отклонить ваш код, если вы используете зарезервированное имя для макроса. - person Jonathan Wakely; 25.03.2014

Стандарт указывает, что имена, начинающиеся с двойного подчеркивания или символа подчеркивания, за которым следует заглавная буква, зарезервированы для внутренних символов компилятора или библиотеки.

Вы указали, что эти приватные символы будут недоступны, но не забывайте о макросах и определениях. По сути, идея так же проста, как «Давайте заменим m_member на _M_member».

Соответствующая часть стандарта — 17.4.3.1.2 Глобальные имена.

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

person NewbiZ    schedule 21.03.2014