6

If we take a look at GNU's implementation of libstdc++, I've noticed that in the implementations of the standard classes that private member functions of various classes are prefixed with _M_. For example, std::basic_string<> has among others a member called bool _M_is_shared() const;.

I understand the motivation to have some sort of naming convention for private member variables. This helps is distinguishing between class members and function local variables visually. But I don't get why the _M_ prefix is preferred for private member functions.

If I see some code that called for example: is_shared(); there is essentially only a few options:

  1. it's a member function of this class
  2. it's a member function of a parent class
  3. it's a global function.

The first two, would both have the prefix so it's no help. The last one wont happen in any sane implementation because of namespace pollution concerns. The only globals the library should introduce are ones prescribed by the standard. So here's the crux of the question...

Since private member functions aren't publicly accessible. Can't effect derived classes in any way. I don't think that name collisions are really a concern here... and basically these are nothing more than a private implementation detail. Why bother with the (IMO) ugly _M_ prefixing? Is there something in the standard that disallows introducing extra private members? If so that would strike me as silly unless there is something I am missing.

Evan Teran
  • 87,561
  • 32
  • 179
  • 238
  • possible duplicate of [Why does the naming convention of STL use so many leading underscore?](http://stackoverflow.com/questions/22319950/why-does-the-naming-convention-of-stl-use-so-many-leading-underscore). It's the same issue, in the GNU C++ library we use `__foo` for locals and arguments, and `_M_foo` or `_S_foo` for members, but in both cases we have to use reserved names to ensure we don't clash with any macros defined by users. – Jonathan Wakely Mar 25 '14 at 14:02

2 Answers2

5

Identifiers beginning with an underscore and then a capital letter, or beginning with two underscores, are "reserved for the implementation in all contexts".

This means it would be illegal according to the Standard for someone's program to #define _M_is_shared false and break the library header file. If they used more ordinary identifiers, there would be greater risk of such a name collision in otherwise valid programs.

aschepler
  • 70,891
  • 9
  • 107
  • 161
  • ah! I hadn't thought about someone using a macro to redefine something private in a header... evil :-P – Evan Teran Mar 21 '14 at 14:54
  • I don't know if it is evil...despite being "reserved" you can still compile code that walks all over reserved naming conventions (which you basically have to allow if people are going to change implementations). The reserved names are a guideline to be more safe, but don't keep anyone from doing anything. – IdeaHat Mar 21 '14 at 14:58
  • 2
    @MadScienceDreams: 17.6.4.3/2: "If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by this Clause, its behavior is undefined." Yes, you can do it, but the Standard specifies that doing so is as bad as dereferencing `nullptr`, and anything that goes wrong is the program's fault, not the implementation's. – aschepler Mar 21 '14 at 15:02
  • @aschepler Sorry, wasn't trying to criticize, you're totally right. Its an AWFUL idea to try and mess with the implementation. I was just pointing out that it is allowed, and that the only reason you'd ever do it would be to change the library implementations. – IdeaHat Mar 21 '14 at 15:22
  • @MadScienceDreams, **no** it is **not** allowed! It is sometimes possible to do, because the preprocessor is stupid and doesn't stop you, but if your program breaks you get to keep both pieces. And a conforming implementation could reject your code if you use a reserved name for a macro. – Jonathan Wakely Mar 25 '14 at 14:09
3

The standard specifies that names starting with double underscores, or an underscore followed by a capital letter, are reserved for internal compiler or library symbols.

You pointed out that these private symbols won't be accessible, but don't forget about macros and defines. Basically, the idea is as simple as "Let's replace m_member with _M_member".

The relevant part of the standard is 17.4.3.1.2 Global names

Each name the contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.

NewbiZ
  • 2,395
  • 2
  • 26
  • 40