28
class C {
 private:
  int member_; // here is the underscore I refer to.
}

This underscore is recommended by Google Style Guide and Geosoft's C++ Style Guide.

I understand that there are different opinions and tastes.

I want to ask people who used it or were forced to use it whether they found it beneficial, neutral or harmful for them. And why?

Here is my answer:

I understand ask motivation behind it, but it does not convince me. I tried it and all I got was a little bit of clutter all over the class, but simpler initialization of members in constructor. I haven't encountered situation where underscore helped to differ between private member variable and other variable (except in mentioned initialization).

In that light I consider this style harmful.

KindDragon
  • 6,558
  • 4
  • 47
  • 75
Łukasz Lew
  • 48,526
  • 41
  • 139
  • 208
  • Subjective indeed. I'm not in favor of this naming convention either. – o.k.w Oct 27 '09 at 12:18
  • Could you state *why* you don't like it? – Łukasz Lew Oct 27 '09 at 12:23
  • 1
    @Łukasz: Trailing underscores are not that easier to 'spot' if you know what I mean. And it's ugly. Ha... – o.k.w Oct 27 '09 at 12:27
  • 1
    I may be crazy, but it seems that putting he underscore at the end is violating other style guides that state the most important variations in a name should be at the start. To me dividing variables into regions (member vs non-member etc) is about as major as you can get - but then again I favour hierarchal conventions. – Peter M Oct 27 '09 at 12:38
  • 6
    But then, you're better avoiding using underscores at the start, because of ANSI C. That is why many also use a `m_` prefix. – Matthieu M. Oct 27 '09 at 13:19

13 Answers13

25

Well since no one mentioned it: adding an underscore to member variable allows you to name your getter and setter with the 'conceptual' name of the variable.

ex:

class MyClass
{
   int someMember_;

public:
   int someMember() const { return someMember_; }
   void someMember( int newValue ) { someMember_ = newValue; }
};

not that I use this style though.

UpAndAdam
  • 4,515
  • 3
  • 28
  • 46
n1ckp
  • 1,481
  • 1
  • 14
  • 21
  • 5
    +1. This is the style I use. I find it very convenient to give the getter/setter the same name. – Rob Oct 27 '09 at 13:15
  • 8
    The question is why you need getters/setters at all. They buy you very little over non-encapsulated, direct member access. If you have that low an abstraction, what's the class for? To me they seem pseudo-OO. – sbi Oct 27 '09 at 14:05
  • Well I agree that having both a getter and setter is usually a smell but this can apply for only a getter (which I think is more justified). Also we don't live in an ideal world and maybe you just need to transition from a public member to using getter and setter before refactoring everything to be "ideal oop". If you want a discussion about getter and setter I think there is a lot of them on this site ;o) – n1ckp Oct 27 '09 at 14:19
  • Although I tend to use m_ and s_ prefixes to accomplish this instead of the trailing underscore, this is my most frequent reason for doing so. I favor protecting class members from getting accidentally hidden by temps. – Phlucious Dec 06 '12 at 19:05
  • For my personal flavour using a prefix (`m_`) does the same job. Also instead of adding a `_` suffix I think it's better to use `this->` whenever you access a member. `this->` makes clear that I am refering to an object contained by `*this`. Also `this` is a keyword that get's highlighted and highlightning is flattering your eyes (except you changed it to pink with green background) :) – Carsten Feb 27 '13 at 13:21
  • 2
    It works for more complex setters that are buying something over raw access too. `void someMember( int newValue ) { validate(newValue); someMember_ = newValue; }` – armb Feb 24 '15 at 17:33
  • Worth noting that this is the convention the C++ Standard Library uses. Cf. `size()`, `begin()`, etc. in many containers (not `get_size()`, `get_begin()`). Same for some of the rare setters, e.g. [`width(streamsize)`](http://www.cplusplus.com/reference/ios/ios_base/width/). Obviously the Standard doesn't say how the member variables should be named but it does prevent naming them the same as their respective "getters" (depending on the implementation). – Emil Laine Jun 19 '15 at 13:29
  • @zenith: `std::setw()`, `std::setfill()`... The C++ standard library is an old beast and has picked up warts of very different origin. The notable difference between `size()` and `begin()` etc. on one side, and [those nasty getters and setters](http://www.idinews.com/quasiClass.pdf) [PDF] everybody seems to be loving on the other, is that the former are concepts inherent to the idea of a container. (It's not much use having stuff in a container if you can't count an enumerate it.) Also, in C++03, `std::list` was allowed to calculate `size()` on demand, rather than fetch a stored value. – sbi Nov 26 '15 at 15:01
  • The main advantage of using getters/setters, even as simple as in the example, over direct member access, is that **in the future** if you need to change the access logic to be more advanced (e.g. add locking or parameter validation), you won't need to **change all the code accessing the member**. Actually, this is probably the main advantage given by any kind of encapsulation - to be free to change the encapsulated implementation without the risk to break clients. I wonder why any experienced developer will argue with this. – Alex Che Apr 04 '17 at 10:38
  • I agree, that *sometimes* the using code is small and/or the probability of the change in access logic is very low. In such cases it may be reasonable not to write the boilerplate access code for getters/setters in advance, and add it only when needed. But it is not the rule, but more like an exception. The importance of getters/setters is so high, that there are special generators for them in some IDEs (like JetBrains IDEA), and even special syntax for them in some languages (like C#). – Alex Che Apr 04 '17 at 10:49
  • @Alex: Why don't you simply read the PDF I linked to in my previous comment? When you have getters/setters for private values, you have already thrown encapsulation out the window and need to rethink your design. Yes, a setter is a higher abstraction than accessing the value directly – but only a marginally higher abstraction. It brings very little benefits, and cannot counter the massive problems due to manipulating the concept of a private datum, no matter through what syntax. – sbi Oct 12 '17 at 18:41
  • @sbi, thanks for your response, even if half-year later. I really appreciate your attention. In the PDF Conrad defines quasi-classes as those, which **have getters/setters for almost every data member**. And then he states that such quasi-classes do not serve any purpose. This does not apply to our conversation though, since I don't advocate classes which have almost all members exposed. I just advocate approach, when if you need to expose **some members**, you better do it via getter/setter instead of exposing the member itself. – Alex Che Oct 13 '17 at 07:00
  • @sbi, you are asking for benefits of getters/setters (as Conrad also does in his article), and I'll restate my previous argument. With getter/setter you are free to later change your implementation: you can add validation, locking, optimization, or you can even remove the underlying member. If you were to expose this member directly, you would need to change all the places where this member were used outside of the class. In some cases it may be burdensome or even impossible. – Alex Che Oct 13 '17 at 07:03
  • @sbi, And no, when we add getter/setter to a class, we do not necessarily throw incapsulation away. Member function `get_x()`, `set_x()` does not actually expose to client, that there necessarily is a member `x` inside the class which is being read and written by these methods. This may just not be true. The members only tell that there is a conceptual property `x` of a class, which may be read and written. How this property is implemented is, well, encapsulated. – Alex Che Oct 13 '17 at 07:04
  • @Alex: I have fought this nonsense too often, I am tired of it. Furthermore, my last comment already contains everything needed to refute your arguments. HAND. – sbi Nov 13 '17 at 14:22
  • @sbi, I'm sorry that you see this conversation as a nonsense fight. I'm not a native English speaker and maybe some of my words came harsh, but I didn't mean this at all. – Alex Che Nov 13 '17 at 20:35
  • @Alex: I am tired of what you said, not how you said it. I have been fighting getters and setters since I was taught they're evil sometimes in the mid-90s. Everything you said I have already refuted – in the very comment you replied to. Plus I have linked to my favorite article about them. Now you can read all that again and find out why I think your arguments are nonsense – or you go on writing these abominations. *shrug* – sbi Nov 15 '17 at 21:52
10

I use "m_" as prefix for normal member variables and "s_" for static member variables. So the scope is directly visible.

swegi
  • 4,046
  • 1
  • 26
  • 45
  • Yes, visibility of the scope is primary motivation for using those prefixes/suffixes. But do you have an example of a situation where knowing variable scope from variable name helps? – Łukasz Lew Oct 27 '09 at 12:27
  • 4
    that's easy - you are in some kind of large method and you inherited from some other guy. You need to find out, what it does. It's a lot easier, if you know the scope of the variable. A local change of a value has much less importance than a change of the class state. That's why you need to know the scope. – Tobias Langner Oct 27 '09 at 12:33
  • @Luke there is always the case of member setter functions where the incoming parameter can then just be the member name minus the underscore. That kind of style aids in overall comprehension. – Peter M Oct 27 '09 at 12:35
  • 1
    I also use "m_" and "s_" for C++. One benefit is that Intellisense can distinguish members and other identifiers then. Therefore I don't think, a trailing "_" is useful. – ur. Oct 27 '09 at 13:40
  • For an alternative to hungarian notation you can check my answer here (although the answer is not directly related to it): http://stackoverflow.com/questions/469696/what-is-your-most-useful-c-c-snippet/1609496#1609496 although it probably add a small overhead but the compiler should be able to optimize it away (citation needed for both claim). – n1ckp Oct 27 '09 at 13:49
  • 8
    I really hate the m_ convention. Member variables are too normal an occurrence for such a startling convention that tends to obscure the variable's actual name. – Omnifarious Oct 27 '09 at 14:52
  • 7
    I wonder how it comes that a trailing underscore is ranted at for being ugly, distracting and whatnot, while the leading `m_`, which is much more of a wart (and _wasn't even asked about_), is up-voted so much by a silent crowd. So much for rational arguments. `:)` – sbi Oct 27 '09 at 15:50
  • @sbi, I can easily come up with at least three arguments. 1. The most important should go in the beginning (easier to spot with eye). 2. Easy to filter in Intellisense by just typing the prefix. 3. Easy to distinguish non-static and static members (how do you distinguish static members using the trailing underscore?) – Alex Che Apr 04 '17 at 11:00
10

If you need this underscore in order to tell class members from other variables, you probably have too large member functions to instantly see what's a variable/parameter.

I still like it because it often simplifies member function parameter naming:

class person
{
public:
  person(const std::string& first_name, const std::string& last_name)
    : first_name_(first_name), last_name_(last_name) {}

  // .......

private:
  std::string first_name_;
  std::string last_name_;
};
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
sbi
  • 219,715
  • 46
  • 258
  • 445
  • 2
    You could of course avoid the hungarian warts by appending the _ to the parameters instead of the members. – digitalarbeiter Oct 27 '09 at 13:53
  • 3
    @digitalarbeiter: Yes, I could. But then I would have to either always add a `_` suffix to parameters (and what would that buy me except for having my own convention that's backwards to everybody else's) or I am back to ad-hoc parameter renaming due to clashes with class members (which to avoid is the reason why I append a `_` to class members). – sbi Oct 27 '09 at 14:03
  • Why not use `person(const string &the_first_name, const string &the_last_name);` Adding an arbitrary decoration to the parameter names in the constructor will *only* appear in the constructor. Whereas `first_name` and `last_name` need to be used many times in the context of the class. It seems the underscore suffix and similar conventions for members sacrifice the readability of the member names in order to make the parameters of the constructor more readable. Does the readability of the constructor parameters names really matter so much? – Brandin Jan 22 '14 at 13:59
  • @Brandin: I guess it's all just a matter of personal preferences. To me, your `the_...` prefix is way more visual clutter than my `..._` suffix. But I insist on neither being objectively being better. I have worked in many projects with different conventions and, no matter how appalling they seem at first, after a few months they all are just another one. – sbi Jan 23 '14 at 13:52
  • @sbi Yes, I agree "the_" or whatever in the constructor parameter list is more clutter. However, this clutter appears exactly once in a class (in the constructor parameter list). It seems that putting "_" on every member is purely to make it convenient to construct objects in the constructor initializer list. I know its not a big deal, but maybe C++ would be considered a more beautiful language if people didn't use such a convention. In the meantime I use whatever convention the team uses, obviously that is more important than personal preferences. – Brandin Jan 23 '14 at 20:28
  • 3
    Actually you don't need the arguments of constructor to differ from member names to do such initialization. Even `:first_name(first_name)` would work here if you didn't use `_` suffix. – Ruslan Apr 06 '15 at 05:52
  • @Ruslan: Indeed, this isn't needed by the compiler. Humans, however, need it. – sbi Apr 06 '15 at 06:58
  • How do you distinguish non-static from static members using this convention (if you do)? – Alex Che Apr 04 '17 at 11:04
7

To me the benefit of this style of decorating member variables is it works well with auto complete functionality of text editors. Having a prefix decoration requires you to type more characters before a solid guess on what you mean can be made.

Andrew Khosravian
  • 1,069
  • 6
  • 13
4

I think it's important to distinguish between class variables and local ones (and global ones if really needed). How you do it, is not important - just be consistent.

class Foo
{
  int mMember;
  int member_;
  int _member;
  int m_Member;
};

All styles give you the information you need. As long as you stay with the same style all of the time, no problem. Sometimes other people need to work with your code (e.g. when you create a library, or you work with a community). Then it might be a good idea to stick with the most used style in the C++ community.

Sorry - I can't answer what style that is.

Igor Klimer
  • 15,321
  • 3
  • 47
  • 57
Tobias Langner
  • 10,634
  • 6
  • 46
  • 76
  • 7
    Avoid leading underscores, there are situations when you should not use them (followed by a upper case letter for example) and it's such a headache to remember exactly what they are... and just too confusing in the end. – Matthieu M. Oct 27 '09 at 13:21
  • 1
    @Matthieu: What kind of situations? Without some examples, that sounds a bit like a "well, we've just always done it that way." Underscore prefixes are widely used, though not exactly standard. –  Feb 09 '12 at 18:17
  • 3
    @JonofAllTrades: The exact rules regarding underscores are: 1. Any identifier using two consecutive underscores or beginning by an underscore followed by an upper case letter are *reserved to the implementation* in **any scope (`\w*__\w*` and `_[A-Z]\w*`)**; 2. Any identifier beginning by an underscore is *reserved to the implementation* in the **global scope (`_\w*`)**. I don't recall the exact paragraph, but it's somewhere on SO. – Matthieu M. Feb 09 '12 at 19:03
  • 2
    @MatthieuM.: Perfect, thanks. For the record, it looks like the main discussion is at http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier. –  Feb 10 '12 at 20:17
  • I started using a leading "\_" (like \_name)for class variables, never had a problem, and they are easier to spot that as a suffix(name_). I also compulsorily use the "this." no matter what, so a setter would read like this: setName(String name){this._name = name;} This way ther is no way you can confuse them. – rciafardone Feb 24 '14 at 05:17
  • So, if you never use leading upper letters in the names of your members, then you never risk to clash with implementation names just by adding a leading underscore. And you only need to think of it once. – Alex Che Apr 04 '17 at 11:11
4

This is basically a religious argument so you're never going to reach a consensus on this style. FWIW, I use this style for my member variables for reasons already stated by others, e.g.:

class Foo
{
public:
  Foo(std::string name, int age) :
    name_(name),
    age_(age)
  {
  }

  std::string name() const { return name_; }
  void name(const std::string& name) { name_ = name; }

  int age() const { return age_; }
  void age(int age) { age_ = age; }
private:
  std::string name_;
  int age_;
};

Just adopt something you're happy with and stick with it.

Rob
  • 76,700
  • 56
  • 158
  • 197
3

I came up with this style independently early in my C++ coding days (late 80s, early 90s) because I encountered several confusing situations in which I had to keep going back to the class header to figure out which variable was really a member variable.

Once I started seeing other people's C++ code that did the same thing I was rather gratified that I had noticed a problem that other people had and that the solution I adopted for myself was something other people also thought of.

It's not frequently useful, but it's fairly innocuous and when it is useful, it's very useful.

This is also why I really hate the m_ style. It's not innocuous, and I think the added ugliness is not worth the benefit.

I do use an S_ prefix for file scope static variables and class static variables that aren't constants. They are sort of like global variables, and I think their use should be signaled loudly.

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • +1 for s_ (or similarly g_) prefix. Like Google's style guide (that otherwise advocates the trailing underscore) they also add a remark to consider prefixing global variables with g_. For similar principles s_ seems comparatively natural, too. – wardw Mar 28 '13 at 15:25
3

This came up in discussion we had where I work but with Java programming. But I think this applies to C++ as well. My answer is that IDE's have a handy function of coloring class member variables. In Eclipse they turn blue. The underscore is superfluous. As another poster put it, "EW, hungarian warts!!". 1980 called and wants it's hungarian notation back.

user866475
  • 31
  • 1
  • I agreee. These various notations were definitely usefull some years ago, but today we have code highlighters even in web forms. And to be honest, color information is more natural to humans than weird characters. It is also much more customizable, every team member can use his own color code, without affecting readability of the code for others. – B.Gen.Jack.O.Neill Oct 20 '14 at 22:50
2

We follow possibility.com's C++ coding standard, which says to prefix member variables with an 'm', but I've also done some work under Google's style guide.

Like you say, it's not strictly necessary, especially if you have an IDE that assigns different syntax highlighting to member variables. However, I think that some kind of consistent naming scheme, to let you tell at a glance whether or not a variable is a member variable, is very worthwhile:

  • Simplified parameter naming, as in sbi's answer, is one benefit.
  • A consistent coding style is important, regardless of which style you pick. Ideally, everyone on the team would use the same coding style, so that you can't tell at a glance who wrote a given section of code. This helps helps when bringing new developers onto the team and with agile practices such as no code ownership and is even more important with open source projects that may attract a variety of contributions.
  • Most importantly, readability can greatly benefit from having all of the code follow a fairly strict style that makes clear the types of identifiers like this. The difference between being able to tell at a glance that a variable is a member and being able to tell from looking at local variables' declarations may be small, but following a good coding standard will make numerous small differences like this throughout a body of code, and it can make a huge difference in how easy the code is to follow and how easy it is to get started in an unfamiliar section of code.

(You mentioned that you gave this style a try, but if it was only for a part of code and only for code that you were already familiar with, then it's harder to see the readability benefit that following a coding style like this for the entire codebase can bring.)

All of this is in my experience, your mileage may vary, etc.

Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
1

there is one more "style" which suggests declaring class members as below:

class Foo{
    int m_value;
public:
     //...
};

i found it usable. but it is just my point of view.

varnie
  • 2,523
  • 3
  • 35
  • 42
  • The difference between m_value and value_ is a single keystroke... Does this really add up to enough time savings to wage battles over it? :-) – MaxVT Oct 27 '09 at 13:39
  • 2
    @MaxVT, it's not the extra keystroke, it's that the m_ prefix has a lot more visual impact and, IMHO, tends to de-emphasize the variable's name, which I think is more important. – Omnifarious Oct 27 '09 at 14:54
1

I agree with Tobias that there's a benefit to some convention -- whatever it may be -- to highlighting class variables. On the other hand, I invariably find that such conventions make the code "flow" less well. It's just easier to read "totalPrice = productPrice + salesTax" then "m_totalPrice = l_productPrice + l_salesTax" or whatever.

In the end, I prefer to just leave all the field names undecorated, and have few enough class variables that keeping track of them is not a problem. In constructors and setters, I put a prefix or suffix on the parameter, or in Java I typically distinguish the class variable with "this.", like:

public Foo(int bar)
{
  this.bar=bar;
}

(Can you do that in C++? It's been so long I don't remember.)

Jay
  • 26,876
  • 10
  • 61
  • 112
  • It would be this->bar=bar, but yes. – Kylotan Oct 27 '09 at 13:39
  • You can do this (albeit the syntax is a little bit different, as Kylotan already noted), but if `bar` is a string, you wouldn't want to. – sbi Oct 27 '09 at 14:07
  • l_ for local and a_ for arguments were used by one of my former co-workers. It made refactoring a b!tch because it ended up producing a delta of almost all lines, due to the names. – Tom Oct 28 '09 at 00:17
  • Kylotan: My question was about the syntax, but rather, would C++ recognize this->bar as referencing the member value and an unadorned bar as the parameter? That's how it works in Java. Or maybe you intended to convey that the answer to that question is yes. – Jay Oct 28 '09 at 05:11
0

I always want to distinguish the class members from the variables. I use the _ as prefix for members and personally speaking this keeps the code clean and readable. Prefixes work fine with the editor's intellisense. Prefixing with m_ or s_ is useful but It looks ugly to me.

thanos.a
  • 2,246
  • 3
  • 33
  • 29
0

I agree with you that the underscore variable suffix is not the ideal coding style, and that adding a little complexity into the constructor is better than adding more complexity throughout the entire class.

The other day, I took a look at one of my old Java projects where I had applied the underscore suffix to variable names, and I found that it did make reading the code more difficult. It wasn't too hard to get used to, but I found it to be slightly distracting without adding any real benefit.

Kaleb Brasee
  • 51,193
  • 8
  • 108
  • 113
  • 4
    You find it distracting because it's an old project and you are now working with a different convention. The same is true for any convention, when you change, you're distracted until you adapt. – Matthieu M. Oct 27 '09 at 13:22
  • I find it distracting because it adds unnecessary characters to a variable name. I would have probably omitted the underscores on that original project, but had to use them due to forced conventions. – Kaleb Brasee Oct 27 '09 at 14:26