What does `m_` variable prefix mean?
Asked Answered
S

10

217

I often see m_ prefix used for variables (m_World,m_Sprites,...) in tutorials, examples and other code mainly related to game development.

Why do people add prefix m_ to variables?

Superintendency answered 21/10, 2012 at 14:54 Comment(7)
See en.wikipedia.org/wiki/Hungarian_notationFabio
Before mindlessly following suit with hungarian notation, please do some history check on what Hungarian notation really is. Because naming an int iCounter is just pointless. But naming an int xAnnotationPos and yAnnotationPos is reasonable. Use the Semantic version.Bemuse
Sometimes, imported modules prefix functions and variables so that you are less likely to overwrite them with your own code. It is a way of 'reserving' names for a specific use.Assay
Byte56 gave you an answer. I have seen tools which rely on a naming convention such as mVariable to generate additional code, documentation (yes) and automate some redundant tasks on some member variables...Manard
While "Hungarian" notation is often viciously derided, the particular flavor of it that denotes variable scope does have some real advantages. In addition to identifying the scope of the variable, it prevents name collisions, as when a local, a parm, and a member all have the same intent, and hence the same "semantic" name. This can make the maintenance of large code bases simpler and less error-prone.Kitsch
Duplicate of Why do variable names often start with the letter 'm'?Sundew
There are arguments for and against any coding standard, but the question clearly asks what is m_ for, yet half the responses here are a commentary on why everyone thinks their current favorite is the best.Trude
O
154

This is typical programming practice for defining variables that are member variables. So when you're using them later, you don't need to see where they're defined to know their scope. This is also great if you already know the scope and you're using something like intelliSense, you can start with m_ and a list of all your member variables are shown. Part of Hungarian notation, see the part about scope in the examples here.

Outrun answered 21/10, 2012 at 14:56 Comment(18)
Worst argument for a naming convention ever, you can simply press ctrl+space for intellisense.Finn
@nightcracker eventhough I don't like the prefix, he means to say that when you type m_ and then " CTRL + SPACE " ( unless it's auto) you get a list only containing your members. Not exactly a good reason but it's a plus.Kordofan
@nightcracker Not sure if trying to be funny or just naive. There was a time before intellisense and there's still a large number of people that don't use it. I'm not saying intellisense is the reason to use this naming convention. I'm saying that's an additional plus if you happen to be using intellisense. Naming conventions are to make code clearer and maintain a standard.Outrun
Worth mentioning that there are lots of other more-or-less standard ways to do the same thing; "m_variable", "m_Variable", "mVariable", "_variable", "_Variable"... which way is 'best' or 'right' (or whether to do it at all) is as contentious and fruitless an argument as 'spaces vs tabs'. :)Verada
I prefer just using "this->" - kinda makes "m_" redundant and is even better as it's enforced by the compiler (in theory you can pop "m_" on any variable type; can't do that with "this->"). Part of me wishes that C++ would just standardize on making "this->" mandatory. But that's going more into the world of discussion than being an answer.Oversubtle
Well, lets not turn it into a discussion. As Trevor said, it's fruitless. The motivation behind naming conventions or which ones to use are discussions that aren't really on topic for this question (or even the site depending).Outrun
@Oversubtle Consistent use of this-> is nice, the problem is indeed that you can't really enforce that. I like this convention though.Funest
@LaurentCouvidou, you can't really enforce that devs create member variables prefixed with m_ either.Rickey
@Rickey Right. It's somewhat easier to review m_ prefixes in C++ as all members are more or less declared at the same place in a header. For this-> on the other hand, I'd say it's more likely to let a few non-prefixed instances slip in method bodies. But yeah, if people decide they don't want to follow this kind of convention, of if they just don't pay attention, you're screwed with both solutions anyway.Funest
+1 for the Ctrl and Space shortcut. I've always used m_, but it looks like I should stop. Using this. followed by Ctrl and Space might be a good way of only showing member variables. It's interesting that in VS2015 if you type this. followed by a member variable, it suggests you simplify your code by removing the this.Stipe
People should probably keep in mind, this convention existed long before intellisense, and not everyone uses Visual Studio...Outrun
Anyway, it's mostly a Microsoft-world, C++ convention style (just like Hungarian, which I don't use anymore in C++ except when maybe referencing or passing vars to C WinAPIs) . I like it for your reasons (intellisense comboboxes and quick to see in raw debuggers such as Windbg). TPub
I know this is old... but it certainly seems like a lot of people whom read this don't even understand why @MichaelHouse mentioned using m_ in conjunction with intelliSense. He was simply stating this not to invoke the intelliSense window but instead to group the variables in the list so it isn't congested with non-member variables. I had to comment as at the time of writing this 23 upvoted the first comment and subsequent comments then layered on the same misunderstanding of the point...but I digress..Abbottson
@Rickey You can enforce this as a rule with such commonly used tools as Clang.Delivery
One thing I would also add to the answer is that having scope based prefix in your naming convention also helps with preventing bugs. Name hiding is common in languages and often wont issue a warning. This can easily happen where someone adds a function parameter that matches an existing member variable name that is being used elsewhere in the function. Using a prefix short circuits this issue. Const correctness can also help with some versions of this issue.Jonijonie
so many young people here! about 15 years ago, when you did a search for naming conventions, the top hit was a style guide that suggested using m_, sort of like airbnb's js guide now: github.com/airbnb/javascript that is the real reason imo. well, it's my reason anyway.Strikebound
take a look at this reasonable answer: https://mcmap.net/q/125447/-what-does-m_-variable-prefix-mean Also, IMHO it's easier to look into a function body and know instantly what is a class member and what isn'tBackus
@Abbottson thank you. It was driving me crazy that no one pointed that out.Theirs
F
137

In Clean Code: A Handbook of Agile Software Craftsmanship there is an explicit recommendation against the usage of this prefix:

You also don't need to prefix member variables with m_ anymore. Your classes and functions should be small enough that you don't need them.

There is also an example (C# code) of this:

Bad practice:

public class Part
{
    private String m_dsc; // The textual description

    void SetName(string name)
    {
        m_dsc = name;
    }
}

Good practice:

public class Part
{
    private String description;

    void SetDescription(string description)
    {
        this.description = description;
    }
}

We count with language constructs to refer to member variables in the case of explicitly ambiguity (i.e., description member and description parameter): this.

Finch answered 25/10, 2014 at 15:20 Comment(8)
Another reason is that in java getter/setter are assumed to be getName/setName, so getM_name is bad and you need handle them one by one.Dispel
Thanks for writing this. I just wanted to point out that the book you quoted has been out since August 2008 -- and I still find this bad practice in new code today (2019).Nosy
C# is a very different animal. It allows us to anonymise a lot of code, and we end up with deep life-time scopes. Consider writing a method that contains a local function that actually calls another method that uses a Func<T> etc, and your call stack starts to grow.. Personally I encourage C# developers to use "this.variableName" (as the good example does) when ever accessing a variable, so you know it is an instance variable. (required in TypeScript) Being lower case (first letter) implies private or local, etc. Sometimes people do something following conventions, but don't understand why.Zyrian
Yes, why use one character when five characters will do?Glabrescent
Microsoft recommends to use the prefix _: Use camel casing when naming private or internal fields, and prefix them with _ . See this link ("When editing C# code that follows these naming conventions in an IDE that supports statement completion, typing _ will show all of the object-scoped members.")Nashbar
for c# this is a really terrible advise. it helps a lot to be able to differ between local variables (myVar) and private fields (_myVar). For everything else converning datatypes the IDE helps you which makes hungerian notation obsolete in c#.Bistort
I just want to note that the example is very biased. IMO the m_ prefix is a very small part of the improvements. The main takeaways from the "good practice" is that you should not abbreviate identifiers and use this when possible. The m_ prefix could easily be added to the good practice without negatively affect it IMO. I am biased though. I really do not like the confusion of non-unique identifiers, even if the compiler might be able to sort it out.Uncivil
No, the code I inherited does not have small classes and functions nor was I asked to refactor them. Adding prefixes makes the code easier to digest.Modestine
A
33

It is common practice in C++. This is because in C++ you can't have same name for the member function and member variable, and getter functions are often named without "get" prefix.

class Person
{
   public:
      std::string name() const;

   private:
      std::string name; // This would lead to a compilation error.
      std::string m_name; // OK.
};

main.cpp:9:19: error: duplicate member 'name'
      std::string name;
                  ^
main.cpp:6:19: note: previous declaration is here
      std::string name() const;
                  ^
1 error generated.

http://coliru.stacked-crooked.com/a/f38e7dbb047687ad

"m_" states for the "member". Prefix "_" is also common.

You shouldn't use it in programming languages that solve this problem by using different conventions/grammar.

Aphesis answered 14/1, 2017 at 18:24 Comment(5)
+1, although do you have any idea where this common practise of having "gets" with only var name comes from?Backus
@Backus I guess it's Ockham's razor. You don't need to prefix other constructs, such as functions, if there's no conflict.Aphesis
@Backus it is "Nouns and verbs" function naming. Nouns are const functions that return object state: name(), width(), color(). Verbs modify state or do work: setName(), run(), quit().Dolphin
@Dolphin whether good idea or not, it is very common, just like _t suffix for types, which is also reserved by POSIX, but people use it anyways.Aphesis
The "_" prefix is not common in C++ and should not be used in code because it is reserved for use by compiler implementers. Some style guides recommend "_" as a suffix for member variables.Dolphin
F
13

The m_ prefix is often used for member variables - I think its main advantage is that it helps create a clear distinction between a public property and the private member variable backing it:

int m_something

public int Something => this.m_something; 

It can help to have a consistent naming convention for backing variables, and the m_ prefix is one way of doing that - one that works in case-insensitive languages.

How useful this is depends on the languages and the tools that you're using. Modern IDEs with strong refactor tools and intellisense have less need for conventions like this, and it's certainly not the only way of doing this, but it's worth being aware of the practice in any case.

Fitment answered 21/10, 2012 at 22:25 Comment(4)
If you have to write this. in your language, then m_ is really useless.Rael
@Rael the m_ is to distinguish it from the property it backs - so this.Something for the property vs this.m_something for the backing member. It's not a convention I prefer myself, but I have mostly seen it used in case insensitive languages (like VB).Fitment
Why not, this.Something for the property and this.something for the backing? Or this._something for the backing? this.m_something is redundant. I use _something so that I don't accidently type it when I go to type Something, nothing to do with membershipness or notCoral
@Coral see my previous comment about case-insensitive languages. Yeah, an _ prefix on it's own would do the job, but m_ is the convention. It's not one that I'd use personally, but if you see it in code that was the intent of the author.Fitment
O
12

As stated in the other answers, m_ prefix is used to indicate that a variable is a class member. This is different from Hungarian notation because it doesn't indicate the type of the variable but its context.

I use m_ in C++ but not in some other languages where 'this' or 'self' is compulsory. I don't like to see 'this->' used with C++ because it clutters the code.

Another answer says m_dsc is "bad practice" and 'description;' is "good practice" but this is a red herring because the problem there is the abbreviation.

Another answer says typing this pops up IntelliSense but any good IDE will have a hotkey to pop up IntelliSense for the current class members.

Observable answered 15/6, 2017 at 8:39 Comment(1)
"but this is a red herring" - Good point. A fair comparison would be m_description vs description.Howells
H
11

Lockheed Martin uses a 3-prefix naming scheme which was wonderful to work with, especially when reading others' code.

   Scope          Reference Type(*Case-by-Case)   Type

   member   m     pointer p                       integer n
   argument a     reference r                     short   n
   local    l                                     float   f
                                                  double  f
                                                  boolean b

So...

int A::methodCall(float af_Argument1, int* apn_Arg2)
{
    lpn_Temp = apn_Arg2;
    mpf_Oops = lpn_Temp;  // Here I can see I made a mistake, I should not assign an int* to a float*
}

Take it for what's it worth.

Heptagonal answered 25/10, 2019 at 15:47 Comment(6)
Awesome. Thanks for the "example". Where it really comes in handy is when you're editing 200,000 lines of code.Heptagonal
No need to get defensive. I'm honestly trying to help you by showing you that there's a mistake in your answer. Let me be more clear, then: It doesn't matter if you have 5, or 200000 lines of code: The compiler will not let you do an assignment with incompatible pointer types. So the point made in the comment is moot.Copalite
Didn't mean to come off as defensive. Sorry.Heptagonal
It's a variation of Hungarian notation, which doesn't make sense in modern languages...Aphesis
it is cool but makes code complex. Decoding also takes some time from developer.Trunkfish
This answer is useful to understand why Hungarian is no longer widely used. It obfuscates the intention that could be provided via a well chosen name and consumes too much development and maintenance time relative to its value. "m_" survived in many C++ code styles because it indicates a "private member" that is unsafe to modify directly outside of an accessor function.Dolphin
F
4

As stated in many other responses, m_ is a prefix that denotes member variables. It is/was commonly used in the C++ world and propagated to other languages too, including Java.

In a modern IDE it is completely redundant as the syntax highlighting makes it evident which variables are local and which ones are members. However, by the time syntax highlighting appeared in the late 90s, the convention had been around for many years and was firmly set (at least in the C++ world).

I do not know which tutorials you are referring to, but I will guess that they are using the convention due to one of two factors:

  • They are C++ tutorials, written by people used to the m_ convention, and/or...
  • They write code in plain (monospaced) text, without syntax highlighting, so the m_ convention is useful to make the examples clearer.
Fructiferous answered 4/8, 2017 at 9:16 Comment(1)
One example could be this: wiki.qt.io/How_to_Use_QSettings Since the Qt Creator IS using highlighting, the first guess might appear. A bit different might be another convention using _object() for private objects of a class and p_variable if it is a pointer since both is not highligted as I know of and seem to make sense for me to use it.Eba
M
4

Others have mentioned that it means a class member. Qt is a popular c++ Framework that uses this notation so alot of C++ GUI tutorial use m_. You can see almost all their examples use m_ for class members. Personally, I use m_ as it is shorter than this-> and feels compact.

Munster answered 7/4, 2021 at 5:31 Comment(1)
In Qt, C++ properties have backing storage that has the same name as the property except prefixed with "m_". C++ code to set a property such as 'person.m_name = "Jane";' is immediately discernible as defective because an assignment to the member variable should only occur in the setter function: 'person.setName("Jane");'. The compiler won't tell you that the "nameChanged" signal will not be emitted because of the direct assignment, but use of "m_" makes it easy to spot the error when writing or reviewing code.Dolphin
S
3

To complete the current answers and as the question is not language specific, some C-project use the prefix m_ to define global variables that are specific to a file - and g_ for global variables that have a scoped larger than the file they are defined.
In this case global variables defined with prefix m_ should be defined as static.

See EDK2 (a UEFI Open-Source implementation) coding convention for an example of project using this convention.

Sri answered 22/8, 2018 at 12:21 Comment(0)
A
3

One argument that I haven't seen yet is that a prefix such as m_ can be used to prevent name clashing with #define'd macro's.

Regex search for #define [a-z][A-Za-z0-9_]*[^(] in /usr/include/term.h from curses/ncurses.

Amiraamis answered 15/2, 2019 at 21:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.