Naming Conventions

This topic is 2350 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Does anybody know of any resources or could offer some advise on choosing naming conventions to make code more readable.

I dont want to use underscores because I find it hard to read.

my initial idea is to use the letter m to precede names of member variables in classes. But then I would have to break this if I had two variables of different types. Like a scale matrix and a scale vector couldnt both be called mScale.

are there any rules or guidelines to follow when doing this?

Share on other sites
mScaleVector and mScaleMatrix? There isn't anything too specific that I can think of in terms of rules and guidelines. Except this: without Intellisense, I should be able to know what a variable is used for/what it does without having to look at more than a couple lines. With Intellisense, I should be able to see the variable's data type, and it shouldn't surprise me.

Share on other sites
Not sure what language you're writing this in? Anyway, in addition to the obvious, I'd suggest having a look at the google style guide - not necessarily to adopt it, but because it provides a rationale for its choices.

Personally I think clarity should always win. Calling something 'scale' when there is an ambiguity as to whether it's a vector or a matrix, requires rethinking the ambiguity:
- should they be a hybrid type that exhibits both properties of a vector and a matrix?
- or should they be two members, in which case they need to be differentiated?

Like Cornstalks I'd go with the latter - at work our naming convention would make me call it FScaleMatrix, FScaleVector; at home it'd be scaleMatrix and scaleVector and at my old job it'd be m_matScale and m_vecScale. The 'm' is almost incidental...

Share on other sites
Thanks thats really helpfull. Really helpfull to see what conventions you've used at work also thanks!

Share on other sites
Naming a variable so it's clear that it's a class member is unnecessary.
If you have too many local variables that can cause confusion, then you need to split up your functions/methods in to smaller part.

As well as if you are consistent in your code you don't need to put Matrix or mat in the name of every declaration,
if scale always is a matrix then you should know that.

Stop thinking about how to restrict yourself and just start creating

Share on other sites
Many people have been asking me to write such a guideline. If I had done so, it would have been helpful here, so I think I will do it soon.

No offense Molle85, but that is not helpful.
If he knows what scale is, and he always makes it that:
#1: Is he not even more restricted?
#2: He and only he knows his code. Naming conventions are not just to help yourself. So he knows what scale is. That isn’t much help to him 2 years from now, nor is it much help for the next guy or girl to view his code.

Class member prefixes are helpful. Very, in fact.

Here are a few suggestions to the original poster, in condensed form:
m_ = Member prefix.
_ = Parameter prefix.
p = Pointer
u = Unsigned.
i = Int.
32 = bits in the type.
f = Float.
d = Double.

Examples:
m_pui32CurPos = Pointer to a 32-bit unsigned int, and it is a class member.
i32Total = 32-bit integer. Not a member of a class and not a parameter.
_ui8Mask = An 8-bit unsigned integer that was passed to the function.

Any naming convention guideline is just that—a guideline. You can feel free to change what you want to suit your personal taste, but the above gives you things to consider and what types of things your naming convention may want to document.
m_ and _ document the origin of the variable.
p documents the fact that it is a pointer.
ui, i, f, and d document the type.
8, 16, 32, and 64 document the size.
C documents that a type is a class.

My guide will also go into details such as:
#1: Put all enumerations first within their scope, then any new structures/typedefs, then members, then functions. Members and functions can be swapped, but enumerations should always be first because structures, functions, and types can rely on them, but enumerations cannot rely on functions, members, or types.
Next comes structures/typedefs, because functions and members can rely on types, but types cannot rely on functions/members.
#2: Make your public class interfaces top of the class declaration, then protected, then private. Follow guideline #1 within these 3 areas respectively.
#3: Use a small comment to indicate your transition from enumerations to types to functions. For example: “// == Enumerations.” After this comment, put all of your enumerations for that scope. Then use “// == Types.”, followed by all of the types you want to declare. “// == Functions.” and “// == Members.” follow.

These are all just things to consider, but one thing on which everyone can agree: When you pick a style, be consistent in that style. A style is useless if it cannot be trusted.

L. Spiro

Share on other sites
Naming a variable so it's clear that it's a class member is unnecessary.
If you have too many local variables that can cause confusion, then you need to split up your functions/methods in to smaller part.
It depends on the kind of programming you're doing.
E.g. here's some code that gets an array of integers, sums the values, and fills the array with 0's.uint numInputs = 0; int* inputs = GetInputs(&numInputs); for( int j=0; j<numInputs; ++j ) { count += inputs[j]; inputs[j] = 0; }Just by glancing at this section of the code, the reader can't see the should-be-obvious performance pitfall. The reader has to take in the entire function, and then use a process of elimination to determine that '[font="Lucida Console"]count[/font]' is probably a member variable because it's not a local, and then notice the horrible pointer-aliasing between '[font="Lucida Console"]this->count[/font]' and '[font="Courier New"]inputs[/font]' and fix the performance bug (i.e. after writing to [font="Lucida Console"]inputs[/font], the compiler can't be sure that the value of [font="Lucida Console"]this->count[/font] is the same as the previous iteration of the loop, forcing it to re-load the member from RAM continually, making the loop 10x slower -- writing into a local, then copying the local to the member will fix this -- an '[font="Lucida Console"]m[/font]' would've made this bug stand out to the reader instantly).

If you're writing the kind of code where you don't have to care what the hell pointer aliasing is, then your needs might be different. If you're doing some kind of programming that requires stupidly long functions, you might want to go as far as using an '[font="Courier New"]a[/font]' prefix on argument-variables, as well as an '[font="Courier New"]m[/font]' prefix on members. If you're doing OO in a non-OOP language, you won't need 'm' prefix as you'll always be using "[font="Courier New"]self.[/font]" etc... Likewise, if you're doing the kind of programming where the size and type of variables is extremely important, then perhaps you should use the horrible MS systems-hungarian style.
A good style should be expressive of the kind of code it's used to write.

Share on other sites
Personal opinion: no to what YogurtEmporer said (in general). Hungarian notation for data types is, in my opinion, an abomination.

Share on other sites
Personal opinion: no to what YogurtEmporer said (in general). Systems Hungarian notation for data types is, in my opinion, an abomination.
^^ Fixed that for you. "Apps Hungarian" is still widely used, due to it not being an abomination

Share on other sites

[quote name='Cornstalks' timestamp='1316396659' post='4863201']Personal opinion: no to what YogurtEmporer said (in general). Systems Hungarian notation for data types is, in my opinion, an abomination.
^^ Fixed that for you. "Apps Hungarian" is still widely used, due to it not being an abomination
[/quote]
Yeah, maybe I should've clarified that. I was referring to systems Hungarian (when I said "for data types", I meant using the data's type as part of the variable name). Apps Hungarian can be useful, and while I still don't like how it mangles variable names, if mangling a variable name is what you need to protect your site from a SQL injection, for example, then it's well worth it.

Share on other sites
As I mentioned, don’t let others tell you what is an abomination. Decide for yourself, unless you have to conform to your company’s style.

L. Spiro

Share on other sites
Honest to goodness, member variables are the IMPORTANT ones. They're the ones that shouldn't need decorating.

Hence, I decorate parameters which happen to collide with members and locals which I can't name anything else. I don't decorate members because they're the ones that the code spends all its time talking about. If you're spending so much time talking about data which is NOT a member that decorating them is a pain, then it's worth having a think about what data the object encapsulates.

Share on other sites
Going nuts with Hungarian notation just adds noise to code. When I want to know about code I've written, it will be obvious from either then interface in the header file or via the parameters I pass to a function. This will still be true a year from now. Do I really need to know that a variable called "worldTransform" is an 4x4 float matrix by tagging the variable name with it?

I decided that for myself!

When working on other people's code, stick to their conventions even if it does mean tagging things with some prefix when the language supports namespaces or putting C in front of every class, in case it wasn't obvious.

Share on other sites
If you having trouble keeping track of classmember vs. local variables, maybe always use this. as you access class variables. Or always use getter/setter ?
Further, with todays modern IDE's and autocomplete having very long variablenames that are very clear is not a problem in my opinion.

edit:

oops, didnt realize this was outside the Java forum, so maybe "this.someVar" do not apply.

Share on other sites

Further, with todays modern IDE's and autocomplete having very long variablenames that are very clear is not a problem in my opinion.

No matter how good an IDE is at autocompletion, if there is a block of code with very long variable names it's probably not going to be very readable.

sum += fnval

or:

sumOfAllTheFunctionValues += TheFunctionValueArray[CurrentIterationIndex]

(exaggerated example of course )

Share on other sites

m_pui32CurPos = Pointer to a 32-bit unsigned int, and it is a class member.
[/quote]
Ugh.... You've dedicate more space to the Type, (i.e. the thing you can see by hovering your pointer over any instance of the variable), than the purpose. What is CurPos? Current position? Cursor position? Something else?

i32Total = 32-bit integer. Not a member of a class and not a parameter.
_ui8Mask = An 8-bit unsigned integer that was passed to the function.
[/quote]
The types for these should be visible on the screen, or within a single "Page Up". If not, maybe you should add "Keep functions short, to less than a single screen if possible" to your convention.

When you pick a style, be consistent in that style. A style is useless if it cannot be trusted. ... Decide for yourself...
[/quote]
These points are certainly true.

Personally, I used to use Hungarian notation when I was an intermediate level programmer. Since then I've changed my programming style such that I find it isn't necessary. Now I find it ugly, distracting, and a maintenance burden.

Share on other sites

m_pui32CurPos = Pointer to a 32-bit unsigned int, and it is a class member.

Ugh.... You've dedicate more space to the Type, (i.e. the thing you can see by hovering your pointer over any instance of the variable), than the purpose. What is CurPos? Current position? Cursor position? Something else?[/quote]
Ironically, although your goal was to propose a situation in which the naming of my variable could be misunderstood, still your first proposal was exactly what was on my mind.
It is the current position, and I named it based off human intuition. Most humans will see it as such when they read it.
Of course, one will be able to decide between the choices you proposed based off whatever kind of function it is, but had I felt the intention of the variable was not clear, I would have made my variable name even more explicit.

i32Total = 32-bit integer. Not a member of a class and not a parameter.
_ui8Mask = An 8-bit unsigned integer that was passed to the function.

The types for these should be visible on the screen, or within a single "Page Up". If not, maybe you should add "Keep functions short, to less than a single screen if possible" to your convention.[/quote]
I hope one day we shall all live in a world in which it will be possible to view only single-screen functions.
But that is not the only threat that variables named without metric information can propose a problem.
Actually, given the types of problems caused by variable metrics, I wonder why metric information would not be available constantly.
It really isn’t a matter of what is convenient. Yes, you can wait for a little yellow balloon to appear. It is not so much trouble. But did you know you were even supposed to show that balloon? Did you even know that the metrics of the variables in play are the cause of the bug?
Without metrics you look only at the algorithm. With metrics, you look at both the algorithm and the implementation of it.

When you pick a style, be consistent in that style. A style is useless if it cannot be trusted. ... Decide for yourself...

These points are certainly true.

Personally, I used to use Hungarian notation when I was an intermediate level programmer. Since then I've changed my programming style such that I find it isn't necessary. Now I find it ugly, distracting, and a maintenance burden.
[/quote]
And still I have used Hungarian for well over a decade and never had a problem with it. My speed at typing ui32 is considerable, and everyone will adjust to whatever style he or she chooses.

The one downside to styles is that they challenge one’s aesthetic perception of his or her own code. A lot of people cannot accept the logical explanations behind how some styles help given how unpleasant the code looks.
Personally, I only feel unpleasant when not all of the code in the entire project is consistent. Whatever the style, I want to make it all look the same.
I recognized early that a lot of people were willing to appease their aesthetic visions of code in order to satisfy their disregard for logic, and I had promised never to be such a person.
That is why you don’t see me talking poorly about any given style or another, and why you can see many places in which I have advocated the choices of each individual.

Let people decide for themselves. People love it when others agree with them, but I am not willing to guide someone down a path he or she did not choose just to make one more person who agrees with me.
The original poster should take all of this as input, filter out what he or she does not like, and use the rest.
Let it be that simple.

L. Spiro

Share on other sites
I just read your style guide. What's with all the LSVOID LSINLINE LSCALL stuff in your class declarations? It reminds me of MFC!

Share on other sites
The code was taken from my engine, which is highly cross-platform.

I have defined macros LSE_CALL, LSE_INLINE, LSVOID, etc., in order to create calling conventions, syntax, and primitive types that are roughly equal across platforms.
In fact, although the Win32 API is essentially just for Windows, the Windows team has recognized this need as well, which is why our results look similar.

L. Spiro

Share on other sites
I see.

I certainly do something similar for floating point numbers and integers for the sake of consistency but inline is inline and void is void. When I compile my game or tools for Windows, OSX or iOS, with the exception of platform specific stuff, I don't need to worry about any of that!

Why do you prefix things with LSE as opposed to namespaces?

Share on other sites
LSE is the namespace in which that macro or variable is defined, but I duplicate it so that it is clear exactly where things are defined when you see it referenced in other libraries.

While some do call it redundant, I am not afraid to be redundant for the sake of clarity. In my #include example, it was immediately obvious that some of those files were included from outside of the LSI library, was it not?

To me, seeing LSI or LSE in things is a constant reminder of the scope of the current library and what other libraries it needs to survive.
To others who may view my code in the future, it is an alert that this library depends on that library, and this is why.

Besides, it is very effective at avoiding name clashes.

L. Spiro

Share on other sites
Sometimes it's just worth taking 30 seconds to come up with a suitable variable/function name, if you need a comment to tell you what this variable does then it isn't named properly.

In fact, everytime you need a comment next to a function declaration you screwed up the name of the function.

You don't need any LP (long pointer) etc... naming conventions if you name your variables properly.

Share on other sites

Sometimes it's just worth taking 30 seconds to come up with a suitable variable/function name, if you need a comment to tell you what this variable does then it isn't named properly.

In fact, everytime you need a comment next to a function declaration you screwed up the name of the function.

I agreed until the end. Functions should always be commented. The name of a function cannot explain how each parameter is used and what side-effects are caused.
I use Doxygen commenting for all of my functions, but again the commenting style is the choice of the developer.

While I won’t suggest one style is superior, I will certainly suggest that at least one style must be chosen here. Every function should have some kind of comment.

L. Spiro

Share on other sites
[font="arial, verdana, tahoma, sans-serif"]

Sometimes it's just worth taking 30 seconds to come up with a suitable variable/function name, if you need a comment to tell you what this variable does then it isn't named properly.

In fact, everytime you need a comment next to a function declaration you screwed up the name of the function.

You don't need any LP (long pointer) etc... naming conventions if you name your variables properly.

[/font]
I definitely agree with that. I keep comments to a minimum and try to let the interface itself do all the talking. Not always possible in the real world, but what I aim for.

Other than that, I find the Google C++ style guidelines match my style well enough.

I agreed until the end. Functions should always be commented. The name of a function cannot explain how each parameter is used and what side-effects are caused.
I use Doxygen commenting for all of my functions, but again the commenting style is the choice of the developer.

While I won’t suggest one style is superior, I will certainly suggest that at least one style must be chosen here. Every function should have some kind of comment.

L. Spiro

Shouldn't the function and it's params tell you what you need to know about side effects? Shouldn't the function name tell you what it does?

Share on other sites

I agreed until the end. Functions should always be commented. The name of a function cannot explain how each parameter is used and what side-effects are caused.
I use Doxygen commenting for all of my functions, but again the commenting style is the choice of the developer.

L. Spiro

True about side-effects (since this isn't a perfect world).

As far as a variable type (is it a pure input, output variable) it is really simple in c++:
you pass it as a const pointer/reference and you know its a pure input. For outputs, I prefix my variables with "OUT" (eg OUTnumElements) and that's that.

I sometimes wonder if I ought to write a comment next to a function about the input/output parameters: if I write a comment it somehow makes me more certain that the inputs/outputs are really what they are meant to be, but on the other hand, everything should be obvious from the variable names (paranoia about future bugs??)

I'm more into the "make a large multiline comment in the .h file and describe how the code is used" instead of "comment everything in your .h and .cpp file". Good code needs little comments, function/variable names must tell you what this function does.

We use comments because of bad naming conventions/bad code design (gigantic functions) and maybe because of the nature of the programming language we cannot properly express ourself via code.