Categories
Game Development

The proper use of Hungarian notation

Joel on Software has a great article about the proper use of Hungarian notation. Basically, most people these days that use Hungarian notation use it to indicate fundamental type to some degree – i for integer, str for string, p for pointer. Usually these types reflect the machine, such as indicating if a variable is […]

Joel on Software has a great article about the proper use of Hungarian notation. Basically, most people these days that use Hungarian notation use it to indicate fundamental type to some degree – i for integer, str for string, p for pointer. Usually these types reflect the machine, such as indicating if a variable is a pointer.

However, the original design had Hungarian notation indicate intent, not type. For example, if you had a calendar display with a month, date, and year, you would have 3 integers prefixed with an m for month, d for date, and y for year. Not i, even though they are all integers.

Joel says it better than I can, but to put it succinctly the first is a waste of time, because you are repeating what the computer already tells you and then having to maintain it as well. The second is quite useful – just as all comments should indicate intent, so should Hungarian notation which is just an abbreviated comment.

In RakNet I will use numBits vs. numBytes. An even better approach is to comment the purpose and scope of variables where declared.

Every game company I’ve worked at except nFusion has used Hungarian notation. Most of the middleware libraries do as well. A notable exception is Irrlicht, which also happens to be one of the friendliest and best designed, though not the most feature-rich.

I’m curious what other game companies and libraries do not use Hungarian notation, vs. those that do.

6 replies on “The proper use of Hungarian notation”

I personally think in this day and age it’s a bit silly. If you aren’t using an IDE that can popup the type and/or the comment that goes with the definition, or allows quick access to the definition then you should upgrade. Not polute the code with extra stuff that also needs to be interpreted and the meaning looked up by other coders.
Of course naming stuff for intent is fine and I do it, but the calender example is a bit much.
I also never put the type before anything either and I rarely abbreviate names of things. Mainly because a modern IDE should indicate it perfectly well when I need to know, through colours/font style/real comments and quick access to the definition without disrupting what I’m doing (in my case VS + Visual Assist)

Ironic that a company called “nFusion” did not use Hungarian Notation. 🙂

I am no longer a fan of Hungarian Notation. At this very moment, I am debugging some refactored code for a video codec. It used to use unsigned shorts for the pixel data, but now it uses unsigned chars (to save memory). Yet all the variables are still named “psPixel”. No one has bothered (or dared?) to rename all those variables to something like “pbPixel”. If the original code just called the variables “pixels” or even “pPixel”, we wouldn’t have this type/name confusion.. :\

I disagree.

Modern Hungarian Notation when done properly is one of the few forms of commenting that actually works. As Chris mentions, no one has bothered to change psPixel to pbPixel and yet it is very easy to force that change… just change the declaration and rebuild (or use VisualAssist’s refactor tool and be done in the time that it takes to checkout your files).

Standard (non-aggressive) commenting however gets out of sync way too quickly and cannot be enforced… there’s no mechanism that forces you to go back and comment all the code affected by the change of a variable or its name.

And no matter how much code you have it is always better to have more information than less information… how is it possible that pbPixel is less informative than pPixel or pixels (again the assumption is that you change it to pbPixel if it originally was psPixel as incorrectly commented code is more of a hazard than a help).

I know a lot of people make the error of assumed casts because they don’t see the original type and no IDE that I know of currently highlights those errors on the fly (including the awesome VisualAssist).

It simply speeds up reading code. For example if I were to see the follow code what should I think…

char pixels[256];

Is it a line of pixels 256 long? Is it a 16×16 pixel image? Or is it a string representing the path to a file that contains pixels. Well I’ve just wasted time thinking about it. And according to the original intent of Hungarian Notation those would be…

char lPixels[256];
char mPixels[256];
char pPixels[256];

The intent is unclear when you abbreviate the intent (there’s too many possible intents)… However using modern type-based notation you don’t lose that intent. Personally I would write those individual items as…

char bPixelLine[256];
char bPixelMap[256];
char szPixelPath[256];

Notice that I provide much more information with no redundancy and I see both the type and the intention of the variable.

I think original Hungarian notation abbreviated the intent because the screen was only 80 characters wide. In RakNet where the intent is unclear or ambitious from the name itself, I spell it out. For example, numBytes vs. numBits.

One reason I like “typed”-hungarian notation because it concisely lets me distinguish between a lot of similarly-named variables.

For example, lets say I’m iterating through an array of filename Strings. And perhaps I need to convert these Strings to c-style null-terminated strings. I would use the variables:

aFileName
strFileName
szFileName
iFileName

To me, this reads more cleanly than:

fileNameArray
fileNameString
fileNameCString
fileNameIndex

I like to use fairly verbose variable names too, so lets say we further had to distinguish between variables like:

szFileNameNoExtention
szFileNameAbsolute
szFileNameRelative

Or even

szPhysicsFileNameNoExtention
szMeshFileNameRelative
szSkeletonFileNameAbsolute

Pretty soon I find myself pretty glad I can pack that extra info into a couple little hungarian notation letters at the beginning of the variable name, leaving me more letters to describe the variable afterwards. I also like how the mixed-case part of the variable name is entirely reserved for a description of the variable, and type is separated off into a concise set of letters which follow a (mostly) standard pattern.

I don’t really buy the argument that using hungarian notation is a waste of time because “the IDE can pop up the type”. The IDE can also pop up header comments for a function. Does that mean I can start naming my functions stuff like:

// This function returns the number of items in the file name array
int a();

// This function indicates whether the user has selected the auto-save option.
bool b():

– and rely on the IDE to display header comments to explain what these functions do? Of course not. There’s a lot to be said for being able to scan and easily mentally parse a chunk of code because of smart commenting and variable/function names.

That all being said, I think people will almost argue whatever they’re most used to working with.

On my own code, I don’t use hungarian notation. Just “m_” for class members.
But at work, we do use it. I was never a fan of Hungarian notation, and never used on a daily basis like this, so I’m still kind of neutral. Not a formed opinion yet.
One thing I’m sure… The time I worked with RakNet, the code was quite easy to follow, and I had no need for that kind of notation! 🙂

Leave a Reply

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