tags:

views:

9129

answers:

9

It's common in C++ to name member variables with some kind of prefix to denote the fact that they're member variables, rather than local variables or parameters. If you've come from an MFC background, you'll probably use "m_foo". I've also seen "myFoo" occasionally.

C# (or possibly just .NET) seems to recommend using just an underscore, as in "_foo". Is this allowed by the C++ standard?

+4  A: 

The following characters are legal as the first character of an identifier, or any subsequent character:

_ a b c d e f g h i j k l m
n o p q r s t u v w x y z
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z

The following characters are legal as any character in an identifier except the first:

0 1 2 3 4 5 6 7 8 9

Microsoft also warns,

Use of two sequential underscore characters ( __ ) at the beginning of an identifier, or a single leading underscore followed by a capital letter, is reserved for C++ implementations in all scopes. You should avoid using one leading underscore followed by a lowercase letter for names with file scope because of possible conflicts with current or future reserved identifiers.

Jacob
That should read: "The following ADDITIONAL characters..."
Andrew
You missed the important bit.
Roger Lipscombe
Added the important bit :)
Jacob
A: 

Yes, underscores may be used anywhere in an identifier. I believe the rules are: any of a-z, A-Z, _ in the first character and those + 0-9 for following characters.

Underscore prefixes are common in C code -- a single underscore means "private", and double underscores are usually reserved for use by the compiler.

John Millikin
They are common in libraries. They should not be common in user code.
Martin York
I agree with Martin on this case.
paercebal
People *do* write libraries in C, you know.
John Millikin
+2  A: 

From MSDN:

Use of two sequential underscore characters ( __ ) at the beginning of an identifier, or a single leading underscore followed by a capital letter, is reserved for C++ implementations in all scopes. You should avoid using one leading underscore followed by a lowercase letter for names with file scope because of possible conflicts with current or future reserved identifiers.

This means that you can use a single underscore as a member variable prefix, as long as it's followed by a lower-case letter.

This is apparently taken from section 17.4.3.1.2 of the C++ standard, but I can't find an original source for the full standard online.

See also this question.

Roger Lipscombe
+80  A: 

The rules:

  • Reserved in any scope, including for use as implementation macros:
    • identifiers beginning with an underscore and an uppercase letter
    • identifiers containing adjacent underscores (or "double underscore")
  • Reserved in the global namespaces:
    • identifiers beginning with an underscore
  • Also, everything in the std namespace is reserved. (You are allowed to add template specializations, though.)

From the 2003 C++ Standard:

17.4.3.2.1 Global names [lib.global.names]

Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.165

165) Such names are also reserved in namespace ::std (17.4.3.1).

Because C++ is based on the C standard (1.1/2, C++03) and C99 is a normative reference (1.2/1, C++03) these also apply, from the 1999 C Standard:

7.1.3 Reserved identifiers

Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
  • Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).
  • All identifiers with external linkage in any of the following subclauses (including the future library directions) are always reserved for use as identifiers with external linkage.154
  • Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

If the program removes (with #undef) any macro definition of an identifier in the first group listed above, the behavior is undefined.

154) The list of reserved identifiers with external linkage includes errno, math_errhandling, setjmp, and va_end.

Some additional classes of identifier names are reserved for future extensions to the C language or the POSIX.1 environment. While using these names for your own purposes right now might not cause a problem, they do raise the possibility of conflict with future versions of the C or POSIX standards, so you should avoid these names.

  • Names beginning with a capital 'E' followed a digit or uppercase letter:
    • may be used for additional error code names. See Error Reporting.
  • Names that begin with either 'is' or 'to' followed by a lowercase letter
    • may be used for additional character testing and conversion functions.
  • Names that begin with 'LC_' followed by an uppercase letter
    • may be used for additional macros specifying locale attributes.
  • Names of all existing mathematics functions suffixed with 'f' or 'l' are reserved
    • for corresponding functions that operate on float and long double arguments, respectively.
  • Names that begin with 'SIG' followed by an uppercase letter are reserved
    • for additional signal names.
  • Names that begin with 'SIG_' followed by an uppercase letter are reserved
    • for additional signal actions.
  • Names beginning with 'str', 'mem', or 'wcs' followed by a lowercase letter are reserved
    • for additional string and array functions.
  • Names that end with '_t' are reserved
    • for additional type names.

Personally I just don't start identifiers with underscores. New addition to my rule: Don't use double underscores anywhere, which is easy as I rarely use underscore.

After doing research on this article I no longer end my identifiers with '_t' as this is reserved by the POSIX standard.

The rule about any identifier ending with '_t' surprised me a lot. I think that is a POSIX standard (not sure yet) looking for clarification and official chapter and verse. This is from the GNU libtool manual, listing reserved names.

CesarB provided the following link to the POSIX 2004 reserved symbols and notes 'that many other reserved prefixes and suffixes ... can be found there'. The POSIX 2008 reserved symbols are defined here. The restrictions are somewhat more nuanced than those above.

Martin York
+1 for the comment.
paercebal
Just a note - with the exception of numbering, what Martin quoted from the draft standard is exactly what's in the C++03 standard (17.4.3.1.2).
Michael Burr
Your summary doesn't say the same thing as the quote from the Standard
fizzer
**global** names are different from "any identifier"
Adam Mitz
@Adam Mitz: Global names also covers MACROS. Which will splatter your identifiers into a mush. This is what I was trying to convey.
Martin York
"Each name that contains a double underscore" - I've always read that as names that start with double underscore. Not that I use double underscores, but now I know I can't.
Michael Burr
Here is the official chapter and verse, please add to your already excellent answer: http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html (and notice that many other reserved prefixes and suffixes you didn't mention can be found there).
CesarB
@Martin York: No argument here, just saying it wasn't clear.
Adam Mitz
The C++ standard doesn't "import" the C one, does it? They import certain headers, but not the language as a whole, or naming rules, as far as I know. But yeah, the _t one surprised me as well. But since it's C, it can only apply to the global ns. Should be safe to use _t inside classes as I read it
jalf
@jalf: The C++ standard is defined in terms of the C standard. Basically it says the C++ is C with these differences and additions.
Martin York
Martin, in the answer you say "This at least means they are not macros.." which i read as "global names are not macros", which i also think they are not. macros are not members of ::, and are thus not global. but in the comment you say "global names also covers MACROS".
Johannes Schaub - litb
what is your final opinion on that? i've seen you added that thing into the answer after you did your comment. so do you have the same opinion as me with that macros are not global names?
Johannes Schaub - litb
Where does the C++ standard distinguish between things reserved "for the compiler" and things reserved "for the OS and libraries", please? I've seen where it reserves names to the implementation, but not where it specifies any distinction between a "compiler", "OS" and "libraries" as components of the implementation.
Steve Jessop
The C++ Standard doesn't "import" the C Standard. It *references* the C Standard. The C++ library introduction says "The library also makes available the facilities of the Standard C Library". It does that by including headers of the C Standard library with appropriate changes, but not by "importing" it. The C++ Standard has an own set of rules that describes the reserved names. If a name reserved in C should be reserved in C++, that is the place to say this. But the C++ Standard doesn't say so. So i don't believe that things reserved in C are reserved in C++ - but i could well be wrong.
Johannes Schaub - litb
This is what I found about the "_t" issue: n1256 (C99 TC3) says: "Typedef names beginning with int or uint and ending with _t" are reserved. I think that still allows using names like "foo_t" - but i think these are then reserved by POSIX.
Johannes Schaub - litb
From the C++ standard 1.1. <quote>C++ is a general purpose programming language based on the C programming language as described in ISO/IEC 9899:1990 Programming languages — C (1.2). In addition to the facilities provided by C, C++ provides additional data types</quote>. My reading of this is that anything reserved in C is also reserved in C++ unless otherwise explicitly stated otherwise.
Martin York
As noted in the main article the '_t' suffix is reserved only by the POSIX standard not the C standard.
Martin York
So 'tolerance' is reserved by POSIX as it starts with 'to' + a lowercase letter? I bet a lot of code breaks this rule!
Sjoerd
@Sjoerd: Probably. Though I am sure that you will be fine as long as `lerance` does not become a real verb that can be applied to characters. Also note it is only reserved in global scope (C)_or the standard namespace (C++) so you can have function variables with this name without breaking the rule.
Martin York
+16  A: 
paercebal
+1 for a rule that is simple, easy to remember, and correct.
A. Levy
+1  A: 

The glibc manual page about that can be found at http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html

Edit: see also http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html

CesarB
A: 

The reserving of the suffix '_t' is a real surprise.

+2  A: 

As for the other part of the question, it's common to put the underscore at the end of the variable name to not clash with anything internal.

I do this even inside classes and namespaces because name mangling is implementation-defined and it is possible that class_name::_variable_name would be mangled into something starting with a _ (because _variable_name starts with a _). class_name::variable_name_ however won't ever get mangled that way.

Max Lybbert
A: 
int S;
int ___S; // RESERVED FOR COMPILER USAGE
int S___;
int _S; // OS & LIBRARIES
int ___S; // RESERVED FOR COMPILER USAGE
int S___;
int _S; // OS & LIBRARIES
int 1___;//error: expected identifier
int 1___;//error: expected identifier int S;
//int  ___; // Reserved