Underscores and Identifiers


 
In preparation for my upcoming GDC presentation in San Francisco, I’ve been reading lots of Standards documents, both C99 and C++03. Fun stuff. I was reminded of some important guidelines for C++ identifiers. Identifiers include macro names, variable names and function names. Consider the following code:
// TreeImpl.h
#ifdef TreeImpl__H
#include <map>
class _TreeImpl
{
private:
   Tree* _pTree;
   // etc.
}
#endif // TreeImpl__H
Looks innocuous enough. But there’s bad mojo hiding here. Here’s what the C++ Standard says (17.4.3.1.2): "Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter is reserved to the implementation" and "Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace."
 
In other words, the identifiers TreeImpl__H (double underscore), _TreeImpl and _pTree (leading underscores) are hidden bombs just waiting to explode. Should some future version of <map> include the following macro:
#define _pTree (_p->_tree_item->getTreePtr())
all hell will break lose. Programmers commonly look at implementation code, particularly Standard C++ header files, see the use of leading underscores and double underscores, and assume they are perfectly legitimate. Don’t fall into this trap. Unless you write compilers and standard libraries, follow these rules to avoid tears:
 
  • Never use double underscores in C/C++ code.
  • Never use leading underscores in C/C++ code.
Update your coding conventions appropriately.
Advertisements
This entry was posted in C++. Bookmark the permalink.

4 Responses to Underscores and Identifiers

  1. Carl says:

    But Pete, aren’t we supposed to use the leading underscore to designate private member variables in C++ classes . . . ?

  2. Unknown says:

    No we’re not. There’s no "standard" coding style for C++, and as such, no specific way you’re "supposed" to designate anything.You’re not "supposed" to designate private member variables in any particular way… other than the one you personally prefer.Some people don’t designate them with anything at all, some use a ‘m_’ prefix, or just ‘m’, and some use a trailing underscore (all of which are legal)A leading underscore is not, however.. (Or specifically, leading underscore followed by capital letter is not. Leading underscore followed by non-capitalized letter is legal, as long as it’s not in the global namespace)Still, if you want to designate private members, use one of the conventions I mentioned to begin with just to be on the safe side.

  3. Unknown says:

    The single leading underscore is not legal regardless of case of the following letter. I’m citing from the ISO/IEC 14882 standard: "Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace."

  4. Unknown says:

    And the rest of names (those contain double underscore and those start with underscore followed by the capital letter) standart reserves "to the implementation for any use." Does it mean that they can be used in the global or ::std namespace as well?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s