Naming Convention - Underscore in C++ and C# Variables

Naming convention - underscore in C++ and C# variables

The underscore is simply a convention; nothing more. As such, its use is always somewhat different to each person. Here's how I understand them for the two languages in question:

In C++, an underscore usually indicates a private member variable.

In C#, I usually see it used only when defining the underlying private member variable for a public property. Other private member variables would not have an underscore. This usage has largely gone to the wayside with the advent of automatic properties though.

Before:

private string _name;
public string Name
{
get { return this._name; }
set { this._name = value; }
}

After:

public string Name { get; set; }

Naming Conventions in C# - underscores

A good article to read on the development of C# style guidelines is here at C# coding conventions.

The original guidance for .NET was to never use underscores unless they were part of a private member variable, and then only as a prefix, e.g. _customerId. This was probably inherited from MFC where 'm_' was used as a prefix for member variables.

Current practice is not to use underscores at all. Disambiguation between private member variables and parameters with the same name should done using 'this.'. In fact all references to private members should be prefixed with 'this.'.

The only place underscore seems to be used a lot is in unit test methods. I'm not a fan, but it may make the methods more readable, for example Throw_If_Customer_Is_Null(){...}.

To underscore or to not to underscore, that is the question

It will have no effect.

Part of the recommendations for writing CLS-compliant libraries is to NOT have two public/protected entities that differ only by case e.g you should NOT have

public void foo() {...}

and

public void Foo() {...}

what you're describing isn't a problem because the private item isn't available to the user of the library

What are the rules about using an underscore in a C++ identifier?

The rules (which did not change in C++11):

  • Reserved in any scope, including for use as implementation macros:

    • identifiers beginning with an underscore followed immediately by an uppercase letter
    • identifiers containing adjacent underscores (or "double underscore")
  • Reserved in the global namespace:

    • 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.1.2 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.

Other restrictions might apply. For example, the POSIX standard reserves a lot of identifiers that are likely to show up in normal code:

  • Names beginning with a capital E followed a digit or uppercase letter:

    • may be used for additional error code names.
  • 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 beginning with PRI or SCN followed by any lowercase letter or X are reserved

    • for additional format specifier macros
  • Names that end with _t are reserved

    • for additional type names.

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 that standard.


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.

why C# and C++ use _ variableName coding convention?

In C# I usually prefix with _ private fields but never local variables. The rationale behind this is that when I need a private variable I type _ and the Intellisense filters the list and it is easier to find. This way I am also able to distinguish between private from local variables and I no longer need to type this.variablename for class fields but simply _variablename.

What does variable names beginning with _ mean?

There's no language-defined meaning - it's just a convention some people use to distinguish instance variables from local variables. Other variations include m_foo (and s_foo or g_foo or static variables) or mFoo; alternatively some people like to prefix the local variables (and parameters) instead of the instance variables.

Personally I don't use prefixes like this, but it's a style choice. So long as everyone working on the same project is consistent, it's usually not much of an issue. I've seen some horribly inconsistent code though...

Why do we use _ in variable names?

It doesn't mean anything. It is rather a common naming convention for private member variables to keep them separated from methods and public properties. For example:

class Foo
{
private int _counter;

public int GetCounter()
{
return _counter;
}

public int SetCounter(int counter)
{
_counter = counter;
}
}

C++ Naming Conventions for C# Developers

There are 3 styles, as far as I know.

First, use underscore:

class Person
{
private:
int _age;
...

You're worried about naming restrictions, but don't worry - first underscore + non-uppercase on non-global names is not illegal.

(first underscore + uppercase is illegal; you must not use names like this: _Age.)

Second, use m_. (m means member.)

class Person
{
private:
int m_age;
...

This style is used in MFC, and I also prefer this.

Third, use underscore, on the last part of name.

class Person
{
private:
int age_;
...

It isn't seen many times, but I've seen it before >o<


Well, you can also name your all class variable normally and use this->.

class Person
{
private:
int age;
...
public:
void SetAge(int age) { this->age = age; }
...

However, this isn't used widely; above all, it's so inconvenient. (Also I have hardly seen this.var style in C# except tool-generated source - is it really widely-used in C#??)

As you see, this-> syntax is used to avoid such a ambiguous situation:

void Person::SetAge(int age)
{
age = age; // what does it mean?
}

(In addition, in the situation like this, age means the parameter; because it's more local than Person::age, so the local age hides Person::age.)

But it isn't used widely as I said. In this situation, It's much better to edit the name of one of ages, than to use this->.

this pointer just means myself; like any other languages which has class, including C#, It is used like this:

void SomeUtilFunction(Person *pPerson);

void Person::Foo()
{
...
SomeUtilFunction(this); // refer to myself
...
}


Related Topics



Leave a reply



Submit