The Religion of Class Member Prefixing

The periodic identifier naming/prefixing/Hungarian-notation religious discussion reared its head recently on Eric Gunnerson’s blog


This particular discussion revolves around the Microsoft-based guideline/anti-guidance of prefixing class member names with “m_” to denote that they are members.  I’ve contributed to many of these discussions over the years and thought it about time to encapsulate my separate remarks to which I and others can refer to.


For the most part I accept this habit with my programmers for a variety of reasons: isn’t guaranteed to do any harm, it’s habit, refactoring tools make it easy to remove “m_”, etc.


When I switched from C++ to C#, I too brought along the “m_” prefix baggage where members can’t be scoped by “this” everywhere (see intializer lists).  I quickly realized it was unnecessary in C#, and haven’t turned back.


Kent Beck’s and Martin Fowler’s Refactoring principles brought us the concept of “Code Smell”.  Code smells are hints (I’m a pragmatist) that something might be wrong with code.  “m_” to me is a bad smell.


When I ask a programmer why “m_” is used the practical answer is invariably “well, the code is too hard to understand without it” (the non-practical answers are usually “Because of the coding guidelines”, or “It’s just habit”, but those don’t answer the “But, why?”).  And this, to me, is a bad code smell.


How complex does a class need to be in order for “m_” to make a difference?  Clearly too complex.  Is the class cohesive?  Does the class and it’s methods follow generally accepted cohesiveness design principles like Law of Demeter or Single Responsibility Principle?  Is the class in inappropriately coupled to other classes?  Have the meaningful-names guidelines been followed?  I’ve never seen a class implementation where a member needed to be so complex (without violating one of the previously mentioned principles) to warrant the need for “m_”.  Occasionally the need to scope a member with “this.” is required; but that’s usually very infrequent, much less frequent than having to type “m_” on every member.


If a class is simple, why should complexity idioms be forced upon it?  “m_” only works if you use it everywhere; if you don’t use it in some places it makes it pointless.  If I’m not sure the programmer just didn’t forget “m_”, and I still have to refer to the class–the task that “m_” is supposed to ensure isn’t needed.  Similar in principle to using const-correctness, something missing from C# programming for the lack of enforcing it consistently.


The topic of consistency is one of the main reasons why I’m not a proponent of “m_”.  There’s no way to enforce use of “m_”, which leaves it up to the programmer.  I’ve dealt with thousands of lines of code from hundreds of other programmers, more often than not inconsistent use of “m_” actually cuased “m_” to make the code much harder to read.  Even the birthplace of “m_” has inconsistent usage of the idiom.  Abram’s and Cwalina’s Framework Design Guidelines (the tome by which all Microsoft code is supposed to abide), as enforced by FxCop and Code Analysis (CA), suggests not using underscore or prefixes (other than “I” for interfaces); yet Eric is a proponent of “m_”.  Much code that comes out of Microsoft (including the .NET Framework) occasionally uses “m_”, often inconsistently.  Using “m_” can cause as many as 4 CA different warnings if the complex rules of “m_” are not followed.  Porting code is a great source for that.


I call it a religious discussion because those who religiously follow the “m_” habit will not be swayed by logic or reason and invariably counter with some edge/corner case that could have made “m_” equally as useful as “this.”, or some logical fallacy, or an appeal to authority they’ve convinced themselves proves their case.


“m_” is less typing than “this.” is a great logical fallacy.  This is a fallacy because it’s only true in that sentence.  Yes, if you have to type “m_” once instead of typing “this.” once, you’ve saved 3 keystrokes (at my typing speed that works out to saving about 300ms).  With the “m_” prefix, that’s now part of the name of the identifier, you must type it every time you type the name of that identifier.  With “this.”, its necessity is based on context, or scope, so its use is optional in most cases and mandatory in some (backed-up with a compiler error, to which you should all agree compile-time checks should be used whenever possible).  An identifier’s un-obviousness of being a member doesn’t occur with every instance of it.  With an effective IDE it can infer the context in which you are typing and suggest what you’re likely typing (Intellisense in Visual Studio).  When using the “m_” prefix you must type at least 3 characters for every single private member of a class  (assuming that’s the guideline) for the suggested completion to be useful.  In cases where “this.” isn’t necessary, you only need to type one character for it to be equally useful.  If you took the average class and analyzed how many keystrokes would be required for “m_” compared to no prefix and “this.” when needed, you’d find that using “m_” is actually more typing.  Ironically, any time that could have been saved using or not using “m_” has been far less than the time spent discussing it.


Other reasons why “m_” isn’t a solution every time it’s used:


  • It’s English-centric.  As such, it becomes more and more arbitrary with speakers of other languages.
  • It’s typically C++-based.  VB programmers have a whole different set of prefixing rules.
  • It’s usage ends up being very contextual.  In C++ “m_” could be mandated all member fields, in C# it could be mandated on only private instance members that aren’t const (and I’ve never seen a clear description of the mandate for example Juval Lowy’s IDesign C# Coding standard is seeminly contradictory: “Use Pascal Case for … constants” providing a example of a private member const named DefaultSize and “prefix private member variables with m_“. 
    Yes, it’s clear that DefaultSize is not variable in nature but the junior programmers to which these guidelines are directed usually don’t pick up on that nuance).

Some discussions on the topic often sway between the “m_” prefix and just an underscore (“_”) prefix.  Some argue that “m_” stands out more than “_”.  Another great logical fallacy because a “Member” suffix should be preferred because it stands out even more.


Regardless of whether prefixing is used, most guidelines mandate that identifiers have meaningful names.  If meaningful names are used, it’s highly unlikely that it will be unclear in the code that a particular identifier is or is not a member of the class.  More meaningful names help in more areas that just distinquishing members from non-members.


For me, my general idioms are: use meaningful identifier names, prefer suffixes to prefixes, don’t use underscores, use Camel Case for field members, and Pascal Case for non-field members (methods, types, constants, namespaces, etc.).  Easy to understand, easy to follow, easy to qualify and enforce…

18 thoughts on “The Religion of Class Member Prefixing”

  1. I have been using camel and pascal case for properties and member variables in VB, like so:

    private _someValue as type

    public readonly property SomeValue()

    get

      return me._someValue

    end get

    end property

    Lately I have noticed that typing the underscore before the word is quite painful, as I am much faster with actual letters.

    What would you recommend? Remember that VB is not case sensitive, so using pascal and camel case for these two is not possible.

  2. In VB, of course, you have a different set of issues that restrict your coding style and guidelines.

    I don’t do any major programming in VB, so I don’t have an idiom for VB.

    I suppose I would likely continue with my preference for English-word suffixes and go with something like:

    Public ReadOnly Property Value() As Integer
    Get
    Return Me.valueStore
    End Get
    End Property

    Private valueStore As Integer

  3. Wow. Seriously?

    That would be to painful for me, typing “Store” I mean. Also, using the “_” suffix allows you to categorize members somewhat, when you’re working inside the current class. This can prove to be quite helpful in avoiding stack overflows etc., although VS2005 does automatically detect potential stack overflows.

    Maybe I should find out another prefix that doesn’t require me pressing the Shift key.

  4. I still use _ for private member variables. Here’s a pointless example.

    class AClass
    {
    private int _currentColour = 0;
    public int CurrentColour
    {
    get
    {
    return _currentColour;
    }
    }
    public void NextColour()
    {
    int calculatedColour = AnotherClass.ModifyColour(_currentColour);
    if(ValidateColour(calculatedColour))
    {
    _currentColour = calculatedColour;
    }
    }
    }

    For me there are two advantages one of which addresses Andrew’s point above.

    First it provides a mental seperation of scope and also allows me to do what I’ve done above. _currentColour is the store for CurrentColour. Ok I could just lose the _ and this code would still work, but then in the method NextColour I already use the prefix free style. I do agree with your supposition that a class really shouldn’t be so complex that it matters, I still maintain it helps though.

    The second reason might help Andrew. I want a private member variable in a method. I hit underscore, maybe one letter and then Ctrl + space. In the example above, _c then Ctrl + Space will of course fill in the entire variable. If I added an _currentColour2 it would bring up a list starting at _currentColour. (Also a good reason to vary variables at the front not the end).

    Anyway, I know if I hit _ and then Ctrl + space I’m going to get a member variable and not a local variable.

    Ian

  5. For me, typing identifiers with underscores are roughly 15% slower to type than those without.

    I’m used to code without them, so the readability aspect doesn’t add anything for me.

    I’m not very religious about it, if I’m in a shop with a strict mandate, I’ll follow it (if I can’t convince them to change :-); otherwise I don’t prefix…

    Given all the places that I’ve encountered that had a strict mandate for prefixes, there were far bigger problems. So prefixes have become a bad smell for me.

  6. I think the important thing is to be consistent. You mention in the post that sometimes people forget to prefix, but I’d argue that if their application of a naming convention isn’t regimented, you’ll have similar problems anyway.
    For example, the MS guidelines suggest all words should be spelt out except in cases where the abbrievation(sp?) is very well known and understood. Developer one adds a variable named kOTimeStamp, and developer two in a seperate bit of code adds kickOffTS. Guess who knew what a kick off was and who knew what a timestamp was. Of course there’s another naming issue there, kO? tut tut tut.

    I think the zealous commitment comes from the comfort factor and the different ways people understand code. Think of it as ORM or more accuratly OMM (Object Mind Mapping) I don’t believe every developer mentally manages code the same way and this is just one manifestation of that. I think there’s a thesis in there somewhere :)
    I have to forego my beloved _ in production code at the moment, but I’m happier with it in my private projects. And I am entirely regimented. There will never be a private member variable without an _ Sir Thank you Sir! ;)

    Ian

  7. OK, in my begginings with C# (but not with OOP, I understood its power lately with DOS TP6.0), I started to use unrecommended prefixes for ABSTRACT classes – simply “A” – because it feels to me quite natural to have “A or An” prefix on SOME abstract thing to which can be “fallbacked”. Similary as “I” prefix is recommended for interfaces and it helps with alphabeticaally sorted intellisense hints (I like purpose sorting much more, MOST of time…). Similary I am prefixing delegate classes with “D”, instead of “Delegate” suffix, again due to intellisense alphabetically sorted … I know that its against FxCop but may be possibly refactored (thanks to God and VS2005, uff:-).

    Simpy, I vote for intellisense hints to be alternativelly sorted by some purpose tags in future. What do you mean?

  8. Hello again, I just popped back to mention an experience I had the other day.
    I decided to download the source code to NHibernate and have a hack around in there. It’s quite interesting, but I keep finding things like this:

    private readonly object _lockObject = new object();
    private ICache cache;
    private int _nextLockId;

    There are even a few like:

    UsualExpectedCount

    I’ve only seen one or two fully capitalised, but it feels like about a 30/70 split between prefixed and not respectively.

  9. Ian: that’s been my experience, prefixing guidelines are not enforced. This means that the prefixing guideline is actually making code harder to read, not easier to read. The code would have been easier to read if no prefixes were ever used.

  10. In this case, I find it worst the lack of consistency.

    Well, coding standards are like any other standards – too many to choose from. And looks like everyone in this project had its own.

    That’s where I draw my line. If you don’t choose the ones I like, choose any other, but, PLEASE, CHOOSE ONE!

  11. I thought it was a good validation of your original point, although I do find it irritating that my prefered style is “bad” because others are unable to be consistent.

    The weakest link of any project always seem be “the others” ;)

  12. Of course the prefix does no good if it isn’t consistent. If it is, though, I find it very helpful in understanding the code. This is especially true when reading the code where tooltips aren’t available, like in an email or hard copy. Also, the prefix groups all member variables together in Intellisense.

  13. @Dave: It’s really what you’re used to. I was used to m_* in my C++ days and felt I couldn’t live without it. Once you switch and get used to it, you can easily read code without member-prefixes (and in fact it’s the opposite for me now, I find it harder to read m_* now…).

    I actually think it makes for more readable code. Prefixing gets people more in the habit of not writing descriptive names. With good naming standards for members and/or locals lack of prefixes can be easier to read (certainly easier to type).

    “this.” also groups all members together in Intellisense.

    But, as I say; it’s more a “style” than anything else, so I’m pretty lenient/accepting of various prefixing rules.

  14. The “m” is certainly redundant. However, as others have mentioned, prefixing groups member variables together in Intellisense and other code listings, which I have found to be very useful. Also, using case to distinguish properties from variables (or any identifiers in the same scope for that matter) is considered poor naming by most professional developers I know; you are just begging for death-by-typo. Given the options, prefixing with “_” has become my own personal convention for private member variables.

  15. I had to stop reading to post the question…are keystrokes really that much of a motivational factor for design and development?

    Coders whining about having to write code. Seriously?

    The next wazoo that mentions “less typing” is gonna get an earful…on the logical level, on the common sense level, on the lazy sob level…I really can’t think of a more inane thing to mention. That will be my new rule: you mention typing or keystrokes and you label yourself unworthy of the compsci discussion we are having.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>