It's common to see a _var
variable name in a class field. What does the underscore mean? Is there a reference for all these special naming conventions?

- 30,738
- 21
- 105
- 131

- 37,207
- 50
- 124
- 185
-
3possible duplicate of [What are the rules about using an underscore in a C++ identifier?](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – R Samuel Klatchko Jun 28 '10 at 22:29
-
I disagree - it's not an *exact duplicate*. The questions both relate to underscores in variable names, but are completely different questions in actual content. (For one, this one asks about C#) – Smashery Jun 28 '10 at 22:31
-
@R Samuel - That is a bit of a stretch. – ChaosPandion Jun 28 '10 at 22:32
-
@Samuel: the other thread seems to focus on C++. In C# there can be other legitimate reasons. E.g. inter-operating with some id**tic case insensitive language, like VB. – Andras Vass Jun 28 '10 at 22:34
-
20Some misguided corporate coding guidelines suggest adding warts to member variables to distinguish them from local variables, out of a belief that classes and functions will inevitably grow so bloated that you can't keep track of what's what without vague clues like this. People who suggest such conventions are all too often the ones whose code most needs them. – Mike Seymour Jun 28 '10 at 22:38
-
28@Mike - Your blanket statement just isn't true. I've found that using this convention makes it much easier to quickly scan methods and get a good understanding of the class. – ChaosPandion Jun 28 '10 at 22:40
-
17In C++, avoid _leading_ underscores. In many contexts (i.e., at global scope, when a capital letter follows etc.) they are reserved for the implementation, and you actually risk having some macro trample over them. So if you want them, make them __trailing underscores__. – sbi Jun 28 '10 at 23:04
-
@ChaosPandion Nowadays, there are extensions to Visual Studio (and probably to other IDEs as well), that can distinguish global-, local and constant variables from each other and present them with different colors. Functions too. Usage of them is more appropriate and even convenient. – Alb Feb 21 '20 at 00:09
-
@MikeSeymour This is savage, lol. – Fantastic Mr Fox Jul 27 '21 at 05:05
19 Answers
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; }

- 10,984
- 4
- 43
- 42
-
12
-
16Identifiers starting with underscores are reserved for the compiler. Using prefix underscores **may** conflict with compiler symbols. – Thomas Matthews Jun 28 '10 at 23:35
-
12
-
13@ChaosPandion I'm assuming that what you mean by "immutable" is actually "read-only", in which case one can use `public string Name { get; private set; }`. True, it's not perfectly immutable, but it's there. – jdmichal Jun 29 '10 at 14:54
-
9@Thomas In a class context, identifiers starting with underscores *followed by a capital letter* a reserved in C++. `_var` is not reserved. – Tyler McHenry Jul 02 '10 at 01:47
-
1@Thomas Matthews - In C# the compiler uses "unspeakable names" for classes and any other compiler generated code. They contain angle brackets '<' and '>' and are not visible in normal code (the brackets are illegal there). – HerpDerpington Aug 14 '13 at 14:32
-
1The underscore syntax is not a convention in C#. It is explicitly prohibited http://stackoverflow.com/a/17937309/1633924 – mcont Nov 26 '14 at 19:20
-
3@Matteo Your use of "*explicitly prohibited*" is overly strong. You are referencing a stylistic guide published by Microsoft, not a language or compiler reference. Different organizations will have different styles. – jdmichal Dec 01 '14 at 16:07
It is best practice to NOT use UNDERSCORES before any variable name or parameter name in C++
Names beginning with an underscore or a double underscore are RESERVED for the C++ implementers. Names with an underscore are reserved for the library to work.
If you have a read at the C++ Coding Standard, you will see that in the very first page it says:
"Don't overlegislate naming, but do use a consistent naming convention: There are only two must-dos: a) never use "underhanded names," ones that begin with an underscore or that contain a double underscore;" (p2 , C++ Coding Standards, Herb Sutter and Andrei Alexandrescu)
More specifically, the ISO working draft states the actual rules:
In addition, some identifiers are reserved for use by C ++ implementations and shall not be used otherwise; no diagnostic is required. (a) Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use. (b) Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
It is best practice to avoid starting a symbol with an underscore in case you accidentally wander into one of the above limitations.
You can see it for yourself why such use of underscores can be disastrous when developing a software:
Try compiling a simple helloWorld.cpp program like this:
g++ -E helloWorld.cpp
You will see all that happens in the background. Here is a snippet:
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
__streambuf_type* __sb = this->rdbuf();
if (__sb)
{
if (__sb->pubsync() == -1)
__err |= ios_base::badbit;
else
__ret = 0;
}
You can see how many names begin with double underscore!
Also if you look at virtual member functions, you will see that *_vptr is the pointer generated for the virtual table which automatically gets created when you use one or more virtual member functions in your class! But that's another story...
If you use underscores you might get into conflict issues and you WILL HAVE NO IDEA what's causing it, until it's too late.

- 47,570
- 62
- 203
- 289

- 2,952
- 2
- 14
- 32
-
9Aren't names that are not global or file scope and start with underscore and a lower case letter perfectly fine? I do this all the time because it's very clean for specific cases, e.g.: void A::set_size(int _size) { size = _size; }. What do yo do for trivial uses like this? – tukra Nov 17 '16 at 20:42
-
@tukra: I wouldn't advise that. If the C++ standard says, not to use names preceded with an underscore or double underscore, then that's what we should all follow. If you really want an underscore, then *I guess* you can place it at the end or in between the name, i.e. size_ (although you are a "hick-up" away from pressing -t- and end up with the std type *size_t*). The issue is that you simply **don't** know when you'll trigger something not intended. Besides, there are other keywords outside of the C++ standard that trigger special compiler handling -> https://en.wikipedia.org/wiki/Restrict – Constantinos Glynos Nov 17 '16 at 22:12
-
7Underscore followed by a lower case letter is allowed in non-global/file scope I believe. Can you show me where in the standard it says it's not? The problem with trailing underscore is I already use that for member vars sometimes. So I might have function 'int size();' member var 'int size_;' and argument 'int _size'. This tends to cover things nicely and I haven't seen better alternatives. Capitalized funcs is not possible for generics that work with STL. The 'this.size' style that C# people like seems error prone to me unless you always use it for member access which is ugly. – tukra Nov 17 '16 at 22:50
-
@tukra: p2, C++ Coding Standards, Herb Sutter and Andrei Alexandrescu. Not sure if the rules have changed in C++11/14, but better be safe than sorry. I'd refactor these names to 1) functions: **get**Size() or **set**Size() (someone using your code **may** conflict size() with the STL::size() using namespaces or aliases), 2) member vars: **m_**size; (also part of the standard), 3) function params: size**_** or **param_**size or **p_**size or simply **size**. Try not to over-decorate your names, because it may lead into trouble. Unfortunately, I don't know C#, so I cannot comment on it's usage. – Constantinos Glynos Nov 17 '16 at 23:43
-
The rules have not changed for C++11/14. Although local scoped identifiers can be preceded with an underscore followed by a lowercase letter, doing so is still very risky as I mentioned earlier, and we should not be looking for trouble when it can be easily avoided. This link (http://stackoverflow.com/a/228797/2754510) includes the rules for C as well. – Constantinos Glynos Nov 18 '16 at 08:41
-
11I understand some people not wanting to use underscore and a lowercase letter because they may have trouble keeping clear what is legal. The C++ standard allows it even if some authors recommend not using it. For me, since it is fully legal and not reserved, I don't see any reason to consider it risky. Thanks for your feedback. – tukra Nov 22 '16 at 18:15
-
3@tukra: It's not **fully** legal. The C++ standard **only** permits you to use a single underscore followed by a lowercase letter in local scope. Good luck! :-) – Constantinos Glynos Nov 23 '16 at 09:49
-
7Sorry. I thought we were past needing to repeat the qualifications. A C++ identifier starting with an underscore followed by a lower case letter is allowed in every scope other than file scope. It is safe and legal in functions, function prototypes, classes, structs, unions, enums and everything you put in a namespace. If you follow the common practice of putting all your code in namespaces then you are completely safe. – tukra Nov 23 '16 at 14:58
-
3@tukra the problem with using `_config` is that it makes it easy to accidentally do `_XMLconfig`, which can conflict with an implementation macro (uppercase abbreviations). Keep in mind a junior maintenance programmer probably has at least a 50% chance of not knowing `_XMLconfig` is bad, so when they see `_config` is fine, they assume `_XMLconfig` is fine. – Peter Apr 29 '17 at 23:56
-
@ConstantinosGlynos, Where can I find the official C++ coding standard? The quote you use above seems to come from here (http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2004/0410/0410mill/0410mill.html), which appears to be an opinion-based book written by someone on the ISO committee, but not the authoritative source itself. – Gabriel Staples Jun 20 '18 at 22:58
-
2@GabrielStaples From the working draft, doc number N4296, Chapter 2.10 - Identifiers: "In addition, some identifiers are reserved for use by C ++ implementations and shall not be used otherwise; no diagnostic is required. **(a)** Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use. **(b)** Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace.". Hope this helps. :-) – Constantinos Glynos Jun 21 '18 at 16:01
-
2@ConstantinosGlynos the standard you quoted says those identifiers are reserved "in the global namespace". It is perfectly legal and widely common practice to use identifiers with leading underscore followed by a lowercase letter within the scope of a class or function. – Bill Weinman Jun 10 '20 at 20:15
-
@BillWeinman: Indeed that is the case for single underscores. However that's not the case for double underscores or single underscores followed by an uppercase letter. Are you ready to sacrifice hours of debugging for a single underscore? Is that underscore so crucial to your code that you must have it? I am not saying it's wrong... I'm only suggesting that you and your team could agree on a standard that can avoid useless frustration. – Constantinos Glynos Jun 11 '20 at 17:40
-
The problem is that most users don't know what the C++ standard says. That's why it's simpler and safer just to never use a leading underscore. In any case, is there really any need to give C++ code a Python smell? A leading "m_" or trailing underscore will do just as well. – Paul Floyd Dec 20 '21 at 09:01
-
@GabrielStaples Herb Sutter (co-author of the book and chair of the ISO C++ committee) is one of the most authoritative sources possible IMO. – Paul Floyd Dec 20 '21 at 09:05
Actually the _var
convention comes from VB not C# or C++ (m_,... is another thing).
This came to overcome the case insensitivity of VB when declaring Properties.
For example, such code isn't possible in VB because it considers user
and User
as the same identifier
Private user As String
Public Property User As String
Get
Return user
End Get
Set(ByVal Value As String)
user = value
End Set
End Property
So to overcome this, some used a convention to add '_' to the private field to come like this
Private _user As String
Public Property User As String
Get
Return _user
End Get
Set(ByVal Value As String)
_user = value
End Set
End Property
Since many conventions are for .Net and to keep some uniformity between C# et VB.NET convention, they are using the same one.
I found the reference for what I was saying : http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices
Camel Case with Leading Underscore. In VB.NET, always indicate "Protected" or "Private", do not use "Dim". Use of "m_" is discouraged, as is use of a variable name that differs from the property by only case, especially with protected variables as that violates compliance, and will make your life a pain if you program in VB.NET, as you would have to name your members something different from the accessor/mutator properties. Of all the items here, the leading underscore is really the only controversial one. I personally prefer it over straight underscore-less camel case for my private variables so that I don't have to qualify variable names with "this." to distinguish from parameters in constructors or elsewhere where I likely will have a naming collision. With VB.NET's case insensitivity, this is even more important as your accessor properties will usually have the same name as your private member variables except for the underscore. As far as m_ goes, it is really just about aesthetics. I (and many others) find m_ ugly, as it looks like there is a hole in the variable name. It's almost offensive. I used to use it in VB6 all the time, but that was only because variables could not have a leading underscore. I couldn't be happier to see it go away. Microsoft recommends against the m_ (and the straight _) even though they did both in their code. Also, prefixing with a straight "m" is right out. Of course, since they code mainly in C#, they can have private members that differ only in case from the properties. VB folks have to do something else. Rather than try and come up with language-by-language special cases, I recommend the leading underscore for all languages that will support it. If I want my class to be fully CLS-compliant, I could leave off the prefix on any C# protected member variables. In practice, however, I never worry about this as I keep all potentially protected member variables private, and supply protected accessors and mutators instead. Why: In a nutshell, this convention is simple (one character), easy to read (your eye is not distracted by other leading characters), and successfully avoids naming collisions with procedure-level variables and class-level properties.class-level properties.

- 2,049
- 3
- 10
- 21

- 1,696
- 12
- 20
_var has no meaning and only serves the purpose of making it easier to distinguish that the variable is a private member variable.
In C++, using the _var convention is bad form, because there are rules governing the use of the underscore in front of an identifier. _var is reserved as a global identifier, while _Var (underscore + capital letter) is reserved anytime. This is why in C++, you'll see people using the var_ convention instead.

- 1,179
- 6
- 9
The first commenter (R Samuel Klatchko) referenced: What are the rules about using an underscore in a C++ identifier? which answers the question about the underscore in C++. In general, you are not supposed to use a leading underscore, as it is reserved for the implementer of your compiler. The code you are seeing with _var
is probably either legacy code, or code written by someone that grew up using the old naming system which didn't frown on leading underscores.
As other answers state, it used to be used in C++ to identify class member variables. However, it has no special meaning as far as decorators or syntax goes. So if you want to use it, it will compile.
I'll leave the C# discussion to others.
You can create your own coding guidelines. Just write a clear documentation for the rest of the team.
Using _field helps the Intelilsense to filter all class variables just typing _.
I usually follow the Brad Adams Guidelines, but it recommends to not use underscore.

- 21,988
- 13
- 81
- 109

- 370
- 3
- 10
With C#, Microsoft Framework Design Guidelines suggest not using the underscore character for public members. For private members, underscores are OK to use. In fact, Jeffrey Richter (often cited in the guidelines) uses an m_ for instance and a "s_" for private static memberss.
Personally, I use just _ to mark my private members. "m_" and "s_" verge on Hungarian notation which is not only frowned upon in .NET, but can be quite verbose and I find classes with many members difficult to do a quick eye scan alphabetically (imagine 10 variables all starting with m_).

- 43,228
- 68
- 238
- 348
-
Since Hungarian notation indicates type, I don't think you could really say that m/s verge on it. – Jerry Nixon May 20 '12 at 04:14
-
@JerryNixon-MSFT Do we identify variable data type and variable visibility type as the same thing when it comes to Hungarian notion? – Necro Jun 19 '19 at 23:48
-
So you don't differentiate between static and instance members with only _, or? – Rekshino Nov 12 '20 at 09:11
The Microsoft naming standard for C# says variables and parameters should use the lower camel case form IE: paramName
. The standard also calls for fields to follow the same form but this can lead to unclear code so many teams call for an underscore prefix to improve clarity IE: _fieldName
.

- 77,506
- 18
- 119
- 157
Old question, new answer (C#).
Another use of underscores for C# is with ASP NET Core's DI (dependency injection). Private readonly
variables of a class which got assigned to the injected interface during construction should start with an underscore. I guess it's a debate whether to use underscore for every private member of a class (although Microsoft itself follows it) but this one is certain.
private readonly ILogger<MyService> _logger;
public MyService(ILogger<MyService> logger)
{
_logger = logger;
}
EDIT:
Microsoft adopted use of underscores for all private members of a class for a while now.

- 1,482
- 3
- 17
- 26
I use the _var naming for member variables of my classes. There are 2 main reasons I do:
1) It helps me keep track of class variables and local function variables when I'm reading my code later.
2) It helps in Intellisense (or other code-completion system) when I'm looking for a class variable. Just knowing the first character is helpful in filtering through the list of available variables and methods.

- 1,550
- 2
- 14
- 18
-
1It is a hassle in a larger method to rely on hover intellisense or scanning to see if a var is defined locally or not. Also prefer "__" for statics for same reasons you mention but it is currently out of favor. – crokusek Jul 29 '13 at 21:37
-
Double underscores for statics would look really nice, but are reserved even inside namespaces. – Sebastian Dec 24 '21 at 10:16
There is a fully legit reason to use it in C#: if the code must be extensible from VB.NET as well. (Otherwise, I would not.)
Since VB.NET is is case insensitive, there is no simple way to access the protected field
member in this code:
public class CSharpClass
{
protected int field;
public int Field { get { return field; } }
}
E.g. this will access the property getter, not the field:
Public Class VBClass
Inherits CSharpClass
Function Test() As Integer
Return Field
End Function
End Class
Heck, I cannot even write field
in lowercase - VS 2010 just keeps correcting it.
In order to make it easily accessible to derived classes in VB.NET, one has to come up with another naming convention. Prefixing an underscore is probably the least intrusive and most "historically accepted" of them.

- 11,478
- 1
- 37
- 49
As far as the C and C++ languages are concerned there is no special meaning to an underscore in the name (beginning, middle or end). It's just a valid variable name character. The "conventions" come from coding practices within a coding community.
As already indicated by various examples above, _ in the beginning may mean private or protected members of a class in C++.
Let me just give some history that may be fun trivia. In UNIX if you have a core C library function and a kernel back-end where you want to expose the kernel function to user space as well the _ is stuck in front of the function stub that calls the kernel function directly without doing anything else. The most famous and familiar example of this is exit() vs _exit() under BSD and SysV type kernels: There, exit() does user-space stuff before calling the kernel's exit service, whereas _exit just maps to the kernel's exit service.
So _ was used for "local" stuff in this case local being machine-local. Typically _functions() were not portable. In that you should not expect same behaviour across various platforms.
Now as for _ in variable names, such as
int _foo;
Well psychologically, an _ is an odd thing to have to type in the beginning. So if you want to create a variable name that would have a lesser chance of a clash with something else, ESPECIALLY when dealing with pre-processor substitutions you want consider uses of _.
My basic advice would be to always follow the convention of your coding community, so that you can collaborate more effectively.

- 1,189
- 5
- 7
There's no particular single naming convention, but I've seen that for private members.

- 88,164
- 40
- 182
- 265
From my experience (certainly limited), an underscore will indicate that it is a private member variable. As Gollum said, this will depend on the team, though.

- 30,738
- 21
- 105
- 131

- 57,848
- 30
- 97
- 128
Many people like to have private fields prefixed with an underscore. It is just a naming convention.
C#'s 'official' naming conventions prescribe simple lowercase names (no underscore) for private fields.
I'm not aware of standard conventions for C++, although underscores are very widely used.

- 14,234
- 2
- 31
- 52
It's just a convention some programmers use to make it clear when you're manipulating a member of the class or some other kind of variable (parameters, local to the function, etc). Another convention that's also in wide use for member variables is prefixing the name with 'm_'.
Anyway, these are only conventions and you will not find a single source for all of them. They're a matter of style and each programming team, project or company has their own (or even don't have any).

- 643
- 4
- 11
Now the notation using "this" as in this.foobarbaz is acceptable for C# class member variables. It replaces the old "m_" or just "__" notation. It does make the code more readable because there is no doubt what is being reference.

- 478
- 5
- 14
-
Really? `m_var` is being replaced by `this->var`, good to know. I use to write `m_var` all the time. But since Qt Creator gives different colors for class members and function variables perhaps is time to abandon that (warts) practice. – KcFnMi Feb 21 '23 at 08:40
A naming convention like this is useful when you are reading code, particularly code that is not your own. A strong naming convention helps indicate where a particular member is defined, what kind of member it is, etc. Most development teams adopt a simple naming convention, and simply prefix member fields with an underscore (_fieldName
). In the past, I have used the following naming convention for C# (which is based on Microsofts conventions for the .NET framework code, which can be seen with Reflector):
Instance Field: m_fieldName
Static Field: s_fieldName
Public/Protected/Internal Member: PascalCasedName()
Private Member: camelCasedName()
This helps people understand the structure, use, accessibility and location of members when reading unfamiliar code very rapidly.

- 32,447
- 15
- 90
- 130
-
3Actually, Microsoft don't recommend to use m_, s_ prefixes. *Do not use a prefix for field names. For example, do not use g_ or s_ to distinguish static versus non-static fields.* http://msdn.microsoft.com/en-us/library/ms229012.aspx – Zied Jun 28 '10 at 22:54
-
2Like I said, take a look at their source code with Reflector. You'll be surprised how much they shirk their own recommendations. ;) As my post mentioned, it helps improve the readability of your code, and my last team really liked the naming convention listed above. – jrista Jun 28 '10 at 23:19