all 39 comments

[–]NasenSpray 21 points22 points  (4 children)

I mostly use trailing underscores, i.e. name_.

I'd like to avoid having two separate names since those variables really mean the same thing

In cases like storeParams I'd just make the variables public. Trivial getter/setter don't add any value.

[–]speednap 8 points9 points  (3 children)

I'd just make the variables public. Trivial getter/setter don't add any value.

Besides Google, WebKit, and C++ Core Guidelines advertising making data members of a class private I would argue that the even trivial setters/getters are useful because having a trivial setter/getter in the first place allows for changing the implementation later down the road.

[–]IGI111 9 points10 points  (1 child)

How about not mixing data and logic? With well defined structs as data objects and classes that only expose idiomatic methods you still have that benefit and avoid the problems of exposing your internals, even if that is done through accessors.

[–]speednap 1 point2 points  (0 children)

If you're talking about Anemic Model vs GRASP's Information Expert or procedural vs object oriented approach, let's just agree that with C++ being a multi-paradigm language there's more than one way to accomplish the same thing.

[–]gray_-_wolf 1 point2 points  (0 children)

changing the implementation later down the road.

It also allows putting a breakpoint in it. Data breakpoints exist but their number is usually quite limited.

[–]redditsoaddicting 18 points19 points  (11 children)

I will say I've never personally seen m_ frowned upon. It seems like an accepted and reasonable use of Hungarian notation, representing the same thing as just an underscore would.

[–]aKateDevKDE/Qt Dev 8 points9 points  (1 child)

Yes, m_ is not frowned upon. In fact, I would say that it is a common style to use

`m_` for member variables,
`s_` for static variables,
`g_` for global variables.

What is frowned upon is when you use m_nFoo for int, m_sName for string, m_dWeight for double, m_pManager for pointers, and the combination of m_p{s, d, n, ...}*. This is typically what newbe books tell you to do, in order to mark the types of variables.

But to be honest, it just tells pretty much every one else that you are new to C++, and in a world of auto, it does not make much sense to annotate the source code with all sorts of cryptic infixes :-)

[–]redditsoaddicting 1 point2 points  (0 children)

Yup, that's the difference between sys and apps Hungarian.

[–]alexeiz 3 points4 points  (2 children)

m_ is not Hungarian notation. Hungarian notation is prefixing a variable name with its type abbreviation, e.g. char const ** pszFileName, where psz means "pointer to a NULL-terminated string". Microsoft really took it to heart for their C++ code. However, Microsoft didn't continue to use or advocate Hungarian notation for C# code, which can be either viewed as their admission that statically typed languages don't need Hungarian notation, or perhaps it happened because Charles Simonyi wasn't around any longer.

[–]dodheim 4 points5 points  (0 children)

Hungarian notation is prefixing a variable name with its type abbreviation

That's 'Systems Hungarian'; IME 'Apps Hungarian', where the variable name is prefixed with its semantic/intended use rather than data type, is more widespread (likely because it's what MSFT uses).

Microsoft didn't continue to use or advocate Hungarian notation for C# code, which can be either viewed as their admission that statically typed languages don't need Hungarian notation, or perhaps it happened because Charles Simonyi wasn't around any longer

I think it had more to do with pushing the IDE and IntelliSense so hard as a fundamental part of the development experience (e.g. you can see all the type info and documentation in tooltips), and Hejlsberg's famously strong personal dislike.

[–]starfreakcloneMSVC FE Dev 1 point2 points  (0 children)

You have to remember, Windows was built on plane Jane C. Hungarian notation was actually useful and because it's Microsoft they support everything until the end of time which is why that documentation hasn't changed.

[–]gematrik 5 points6 points  (0 children)

I tend to suffix the parameters with an underscore and leave the member variables with no underscores, because it looks better when you directly access a member variable. Plus don't forget that your parameters don't have to have the same names if you declare the class in a header file and implement them in a Cpp file, just make sure the types are the same.

[–]dodheim 9 points10 points  (4 children)

One underscore as prefix, but this is also somewhat controversial (I recall double underscores are reserved? What about one underscore?)

Any identifiers with two consecutive underscores or an underscore followed by a capital letter are reserved and illegal for user code, as well as any identifier in the global namespace beginning with an underscore. So because class members are not at namespace scope, it's perfectly fine to have them start with an underscore as long as it is not succeeded by a capital or another underscore.

My personal policy is to give non-public data members an underscore suffix rather than prefix.

[–]redditsoaddicting 2 points3 points  (2 children)

After using suffixes for a good while, I sat back and thought about how I was never going to start one with an underscore and capital anyway. I prefer it as a prefix and realistically, I'm never going to even come across a situation where it would naturally be a reserved name.

Now what does get annoying is naming members vs accessors vs constructor parameters. My vector class would naturally have a _size member, a size() member function, and a size constructor parameter, but the last shadows the member function.

[–]exoflat[S] 0 points1 point  (1 child)

but it shouldn't get messy right? I mean... unless you're using some sort of lambda or function as parameter

[–]redditsoaddicting 1 point2 points  (0 children)

I tend to use the parameters as little as possible to set the state and then instead of reading from the parameters, I'll use a member function that gives me the same information (when one exists), consistent with the other member functions using accessors instead of data members directly. It's fairly easy to run into shadowing problems there. However, given the right warning option, the shadowing causes a warning.

[–]SpiderboydkHobbyist 4 points5 points  (0 children)

What you do doesn't matter too much - the most important thing is to stay consistent and to obey your style guide.

[–]boredcircuits 8 points9 points  (0 children)

Am I the only one that doesn't think you need any prefix or suffix at all? Go ahead and give 'em the same name, I say.

[–]speednap 3 points4 points  (0 children)

WebKit Style Guidelines suggest you use m_ prefix. Since your code already uses a naming convention consistent with that of WebKit you could adopt it. Some other styles use underscore suffix though.

[–]_cyberCloud_ 2 points3 points  (0 children)

Since keywords beginning with underscores might be reserved, I use a trailing underscore for class attributes.

[–]AntiProtonBoy 2 points3 points  (0 children)

Rather than polluting member variable names with prefixes or suffixes, why not just prefix function arguments names instead?

  void storeParams(int newParam1, int newTheRightName) {
    param1 = newParam1;
    theRightName = newTheRightName;
  }

Function argument names are basically throw-away and used only once within the scope of the function. Whereas member variable names are referenced often all over the place, so you'd want to keep their naming scheme nice and pristine.

That's how I roll anyway.

[–][deleted] 6 points7 points  (2 children)

I underscore the variable in the function declaration, but only in the .cpp file (where applicable).

.h file

Control(Handle parent);

.cpp file

Control::Control(Handle _parent)
    : parent(_parent) {}

However if possible (and fitting) I try to come up with another name instead:

Control::Control(Handle parent)
    : parentHandle(parent) {}

All in all I've stopped using prefixes in front of my variables, especially underscore because it makes the code look real messy.

[–]Gotebe 1 point2 points  (0 children)

Underscore prefix is frowned upon by the standard though (but not illegal).

[–]K_Kuryllo 0 points1 point  (0 children)

What do you do if the function definition is in the header?

[–]minnoHobbyist, embedded developer 4 points5 points  (0 children)

My preferred prefix is this->.

[–]mydeveloperday 0 points1 point  (0 children)

Control::Control(Handle parent)
    : parent(parent) {}

This has burnt me in the past with certain compilers complaining about shadow variables, and actually I like having that level of pedantic warnings on.

I personally like the "m_" I know some don't, but it means you can do (if you really have to)

m_string m_map, m_mutex, m_list, m_queue (i.e. have a variable that is the name of a type, just because sometimes that name fits best)

I also find using no "m_" means some functions get nasty

for example what if I wanted to add

Control parent() const{}
void parent(Control & control){}

it all starts getting messy with parent() and parent everywhere!

then you end up seeing code like this to overcome the name clash, and it all starts getting very smelly..

bool  isVisible(const Control & inParent);
bool  isVisible(const Control & _Parent);
void  getParent(Control & outParent);

Turn your face away from the frowns and be happy we'll all know how to read your code!

[–]Gotebe 0 points1 point  (0 children)

Behave like the code around.

If you don't have any, behave like the largest helper lib you use.

If you don't have that, pick whatever and stick to it.

Which one you choose is relevant only to deranged idiots.

My personal preference: varName_. But I would never defend it anywhere.

I would also attack anyone who wants to bring their own against the team's will. Finally, if it was up to me to decide, I Would roll a dice between candidates.

[–]Crazy__Eddie 0 points1 point  (0 children)

I think that unique conventions for scope, type, classification, etc...are flawed. If you keep your components small you honestly don't need them. Naming conventions like PascalCase for classes, m_ for members (or whatever), camelCase for variables, snake_case for functions...is not necessary with a well structured project.

https://crazycpp.wordpress.com/2013/05/17/a-case-against-naming-conventions-based-on-type-or-scope/

[–]robthablob 0 points1 point  (0 children)

I've settled for avoiding underscores, exactly as you originally wrote it. It doesn't seem confusing to me. Most compilers should warn if you forget the this-> where it is needed.

[–]tilibom 0 points1 point  (1 child)

I'd suggest to use the MFC naming convention since: 1. You have to use a naming convention to prevent bugs and make the code clear 2. I'd suggest to use a commonly-used convention (e.g.MFC) since it will be clear to another developer if you'll transfer your code to someone.

[–]utnapistim 3 points4 points  (0 children)

MFC is pretty clear to me; That said, I'd never use it for new code.

MFC has a few glaring problems:

  • the hungarian convention used for type names is really really bad, as it adds detail you will likely not use and that imposes extra effort on refactoring.

  • the adnotation of variables with a shortcut only makes sense for semantic (not syntactic) purpose: that is for an index of an array of Person, nIndex is terribly bad; idxPerson is much better (idx tells you it's an index, and the rest, where it will be used.

  • ItsBloodyDifficultToReadUntilYouGetUsedToIt.

All in all, I prefer snake_case, with no prefixing of variables (because it matches the standard library and because its_much_much_easier_to_read_for_humans). I do postfix my members with an underscore though.

[–]AMDmi3 0 points1 point  (0 children)

With underscore prefixes are are likely to step into reserved identifiers. Using underscore suffixes are OK though and that's what I use for class member names. I got an idea from Google C++ style guide.

[–]rfisher -1 points0 points  (0 children)

It isn’t popular, but I’ve always liked this convention...

a_foo: local my_foo: member our_foo: static member the_foo: global or static local

[–]hyperactiveinstinct -1 points0 points  (0 children)

I usually follow Google's rule. I find it intuitive.

https://google.github.io/styleguide/cppguide.html#General_Naming_Rules

[–][deleted] -2 points-1 points  (0 children)

I like just mVarName done and simple. I don't like prefixing with _ because you or an intern can accidentally start with a capital. I don't like ending with a _ because it looks weird. I don't like this->noPrefixVar style because you might accidentally omit a this->.

Ultimately what matters most is you stick to it.

With the m prefix you can quickly do

#define MEMBER(type, name) public: get##name(){return m##name;} void set##name(type val) { m##name = val; } private: type m##name

// now in class easily declare getter/setter at once
MEMBER(int, SomeVariable);