Convention of using underscores in C++ class member names
Asked Answered
H

7

6

The large majority of my programming knowledge is self-taught, so I was never taught proper design patterns, conventions, and so on and so forth.

I've been digging through a lot of my company's software libraries lately, and I notice that a lot of class data members have underscores in their names.

For example:

class Image
{
// various things

// data members
char* _data;
ImageSettings* _imageSettings;
// (and so on...)
};

I see this in a lot of online example code as well. Is there a reason behind this convention? Sorry I couldn't provide better examples, I'm really trying to remember off the top of my head, but I see it a lot.

I am aware of Hungarian notation, but I am trying to get a handle on all of the other conventions used for C++ OOP programming.

Hin answered 26/7, 2011 at 4:15 Comment(2)
A reason for me to use this convention (in other languages as well), is to avoid making mistakes where I declare a method local variable that has the same exact name as a class instance variable.Blake
Also see: https://mcmap.net/q/20769/-what-are-the-rules-about-using-an-underscore-in-a-c-identifier/14065Dennadennard
A
6

It is simply intended to make it clear what variables are members, and which are not. There is no deeper meaning. There is less possibility for confusion when implementing member functions, and you are able to chose more succinct names.

void Class::SomeFunction() {
    int imageID;
    //...
    SetID(imageID + baseID); //wait, where did baseID come from?
}

Personally, I put the underscore at the end instead of the begining [if you accidently follow a leading underscore with a capital letter, your code becomes ill formed]. Some people put mBlah or m_Blah. Others do nothing at all, and explicitly use this->blah to indicate their member variables when confusion is possible. There is no global standard; just do what you want for private projects, and adhere to the existing practices elsewhere.

Achlorhydria answered 26/7, 2011 at 4:25 Comment(1)
Let's see - baseID is not a parameter to the function and not declared locally, so it must be part of the class state. What else could it be? Surely not some random global variable!Larval
C
4

I have seen _ typing in front of the member, just to notify the reader that it's a class member variable.

More conventional way I have seen is putting m_; i.e. m_data;

Claxton answered 26/7, 2011 at 4:22 Comment(3)
C++ reserves names beginning with two underscores or an underscore and an uppercase letter, as per ISO C++ 17.4.3.1.2.Clerkly
@Don, thanks, I missed the part that _ should be followed by uppercase letter. Edited.Claxton
@iammilind: You mean should notDennadennard
M
3

Usually underscore before a member is used when the member is private.

It is usefull in language that does not have a builtin way to declare members private, like python.

Millburn answered 26/7, 2011 at 4:24 Comment(2)
Hi @Andre, may I ask why an underscore is usually used for a private member, but not for public members?Vertievertiginous
The underscore is a way to distinguish a private member from a public one, so who is using the class knows that it will not be correct to access the member that starts with underscore. I think this concept of prefixing private members came from tools that list the members alphabetically, all the private members would be shown before (or after) all the public ones.Sike
C
2

Usually an underscore is used in member variables so as to distinguish between member variables, static member variables & local variables.

m_ is used for normal member variables &
s_ for static member variables

This way the scope of the variable is visible in the variable name itself.


Also, sometimes underscores are used in member name so that you can name your get and set methods with the member name itself.

For example:

class Image 
{ 
    // various things  
    // data members 
    char* _data; 
    ImageSettings* _imageSettings; 
    // (and so on...) 
    public: 
    ImageSettings* imageSettings()
    {
        //return pointer
    }
    void imageSettings(ImageSettings *ptr)
    {
        //set member variable value
    }
}; 

However, different organizations adopt different conventions & coding styles and one should stick to them. Follow the principle,
When in Rome think & act like the Romans :)

Codee answered 26/7, 2011 at 4:24 Comment(3)
I hate conventions like this. If your code is not clear enough to distinguish local from member variables without the extension there is something more fundamentally wrong with your code. Trying to compensate with prefixes in my opinion just obscures the problem, forcing people to write clear comprehensible code would be a better solution to the problem.Dennadennard
@Martin: I said "Usually". In my experience that is the justification for underscores I usually encountered. I don't endorse it, Sometimes I do use the second way for naming functions same as variables, but as I said, coding conventions & style purely vary from organization to organization and I stick to those, whtever they maybe it's too much of an overhead to convince people to change something they have been using for years.Codee
Thank you @AlokSave for clarifying m_ and s_. I always wondered what m_ means. Also, I agree that the naming convention may not be ideal, but what brings me to this question are the hundreds of existing m_s in a codebase that I hoped to understand.Vertievertiginous
D
1

I don't think there is a universal rule for naming. However, one of the most important one is to stick to what's already used in your company/project. Don't break it. Otherwise, it's most likely that your tech lead or mentor will challenge you about it.

For your reference, Google C++ style for naming

Dentoid answered 26/7, 2011 at 4:20 Comment(3)
What are those of us who violently disagree with the Google style guide to do? :)Gaut
Google has a huge problem with legacy code and is in no way a model for C++ development.Larval
Yes, that's why I said there is no universal rule that everyone agrees:) This is one of the public styles we can find on web and it's just for OP's reference, again.Dentoid
W
0

What I've learned is that having an underscore before or after a variable means that it's a member of that class - private, public, or protected.

Wisteria answered 26/7, 2011 at 4:20 Comment(0)
C
0

The reason for this convention is that member names beginning with underscores show up first in Intellisense. Generally, you have to follow the convention of the project you are contributting to. If you are starting a new project, it is a good idea to follow a commonly accepted convention, such as Sutter's and Alexandrescu's C++ Coding Standards.

Clerkly answered 26/7, 2011 at 4:23 Comment(8)
I think this convention long-predates intellisense.Gaut
Because it's in the C standard from 1989.Gaut
I do not see where ANSI C recommends beginning member names with an underscore. Can you point out the paragraph?Clerkly
No, ANSI C explicitly prohibits most such names. I'm saying the leading underscore as a naming convention, not that particular use.Gaut
The specific convention of using leading underscores for member variables, as opposed to trailing underscores or other kinds of prefixes, in my opinion, clearly exists for the sake of Intellisense (or ctags). I have not seen it being widely used before mid-nineties. Other uses of leading underscores are not really relevant here.Clerkly
Then we can agree to disagree. I wouldn't even call it a convention -- because the standard disallows use of leading underscores it's about the first thing I'd change in a code review.Gaut
The standard reserves names beginning with two underscores or an underscore and an uppercase letter (17.4.3.1.2). Come on, you are just quibbling now. If you have evidence that the convention predates intellisense, I am perfectly willing to withdraw my statement. If not, there is nothing to argue about. :)Clerkly
What I mean is, those names are effectively private to the compiler. They're using a name with a leading underscore to signify implementation details, which is exactly what it's used for now. There are plenty of us who write code without things like intellisense who use this convention. (Really, anyone with a large project who was using Visual Studio 2005 or 2008, because intellisense doesn't work worth a damn there)Gaut

© 2022 - 2024 — McMap. All rights reserved.