Reputation: 69815
I have some code that has a dynamic-class system in C++ that has a member called GetClassName(), a rather harmless name one would imagine. However when included in a large project with Windows headers all hell broke loose. Apparently Windows uses a #define GetClassName (GetClassNameA or GetClassNameW) which screws up everything, and my virtual call tree became all messed up making me lose a day in stupid compiler debugging in the dark, trying to figure out what was wrong.
So besides the point that I'm cursing Microsoft for using such a horribly easy to clash name for a #define (I mean someone should honestly be shot for this!) I'm asking for 3 purposes.
Upvotes: 5
Views: 4558
Reputation: 1942
I would rename the method.
Of course one can say
#include <windows.h>
#undef GetClassName
but it is not clean, users of one's code should remember to write ::GetClassNameW when they call win32 function.
One can provide GetClassNameA and GetClassNameW methods in his class, but it's plain ugly.
I see two approaches : either lengthen or shorten the name:)
1) add a prefix for all functions in the subsystem, f.e TI_ (for type info):
TI_GetClassName()
TI_GetBaseClass()
TI_IsDerivedFromClass()
etc
2) or put them into some IClass interface
interface IClass {
GetName();
GetBase();
IsDerivedFrom();
etc
and return that interface from single method,
so that GetClassName() becomes
GetClass()->GetName()
Upvotes: 4
Reputation: 29047
The Windows API is chock full of macros with clean names that expand to function names with a suffix indicating ASCII/UTF-16, dependent on build options. It would have been nice if they prefixed everything with "W32" or similar (a la "NS" on OS X), but they chose not to presumably to keep the API "clean".
Since it's a lot easier to change your code than their API, here are a few suggestions:
1) Learn the Windows API (it's actually not that big!), or at least become familiar with MSDN so that you can look for name clashes when you encounter inexplicable program flow.
2) Use explicit scope resolution in your code where you can (MyClass::GetClassName()). Unfortunately, this will break virtual function dispatch, so be careful with this.
3) Use a different naming convention in your code. MS always uses CamelCase, so you won't clash if you pick some other convention (get_class_name(), getClassName(), etc.).
4) Personally, I hate naming my getters & setters "GetX()" and "SetX()", but prefer to lean on the overloading mechanism and use "xtype X() const" for getters and "void X(xtype newval)" for setters. Your mileage may vary, but I find it cleaner & the get/set is obvious from the arguments. Obviously you have to be careful if you're using default arguments.
Good luck!
Upvotes: 2
Reputation: 754545
GetWindowClassName perhaps? In reality GetClassName is not a bad name for this API as it relates to window classes. The real problem is that it's a C API declaration and C declarations have no way to introduce a re-usable declaration which doesn't pollute the global namespace.
This is much more a failing of the C language than microsoft.
Upvotes: 2
Reputation: 159590
ClassGetName()
#undef GetClassName
#include
them. Upvotes: 6