I'm not a fan of Hungarian notation for variable names, particularly the variety where static type information is encrypted into impenetrable acronyms and repeated redundantly with every variable access. As the authors of The Pragmatic Programmer would say, it violates the DRY (Don't Repeat Yourself) principle. If you change the variable's type, then you need to make sure to rename the variable as well or the Hungarian notation becomes a trap to mislead those who maintain the code in the future.

Let's take a look at an example of Hungarian notation gone bad. I stumbled on to it when a colleague pointed me to this blog post about FxCop saving the day from misleading documentation. (FxCop has a handy rule which can flag the most common source of portability bugs in managed code: passing incorrectly sized integer arguments to common Win32 API via P/Invoke.) The troublesome API in question is HeapCreate which (assuming you don't pick up the WinCE docs by mistake) has the following signature:

HANDLE HeapCreate(
    DWORD flOptions,
    SIZE_T dwInitialSize,
    SIZE_T dwMaximumSize);

Wait a second; doesn't the dw prefix mean DWORD, which is always 4 bytes wide whereas SIZE_T is 4 bytes wide on 32-bits platforms and 8 bytes wide on 64-bit platforms? I presume that the initial and maximum size arguments were first typed as DWORD, but needed to become SIZE_T to support the larger address space in the move to 64-bit. Unfortunately, nobody bothered to change the parameter names accordingly.

For the record, the correct P/Invoke declaration for HeapCreate is as follows:

[DllImport("kernel32.dll", SetLastError=true)]
static extern IntPtr HeapCreate(
    Int32 options,
    UIntPtr initialSize,
    UIntPtr maximumSize);

Notice how I left out the Hungarian notation. Good riddance!