Mentality behind GNU _M_ prefixing
Asked Answered
T

2

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.

Tessi answered 21/3, 2014 at 14:42 Comment(1)
possible duplicate of 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.Zellers
T
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.

Tragedy answered 21/3, 2014 at 14:50 Comment(5)
ah! I hadn't thought about someone using a macro to redefine something private in a header... evil :-PTessi
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.Slain
@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.Tragedy
@Tragedy 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.Slain
@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.Zellers
C
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.

Colloquium answered 21/3, 2014 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.