I have sometimes a mixed feeling about MACROS, but today I found 2 reason to hate them a bit more than I like them!
I fact I work with a library and I wanted to define a simple C++ mapping table to translate one on that library enum into other value (as int), so I wrote:
static std::map<LibName::Level, int> LibLevelToExternalLevel_Map = boost::assign::map_list_of(LibName::INFO, 40000)(LibName::TRACE, 30000)(LibName::WARNING, 60000)(LibName::CONTROL, 40000/*map on INFO*/)(LibName::ERROR, 70000);
Note that modern C++ provide the initializer list but I’m still in the old age, using C++9… the shame on me !
And to get back on my topic, as I compiled that code, one of my compiler started to complain. From GCC POV that code was ok but from VC98.
(380) : error C2589: 'constant' : illegal token on right side of '::'
As often in that case, you can suspect 2 things:
- compiler bug
- preprocessor bug
I try to find which “LibName::XXXX” label caused the issue and I found that ERROR was the root of the problem….. And after more investigation I found that a windows.h file was include at some point in the .h tree I used for that cpp file.
You may be not aware, but if you include <windows.h> a macro ERROR will be define and it was the root of my issue. A naming collision…. And it’s not the 1st time I had collision in that cpp file. The lib I use also has a class with an API (public function member) call GetMessage, but to build under windows I have to un define a macro for a while….
#ifdef WIN32 #ifdef _UNICODE #define GetMessage GetMessageW #else #define GetMessage GetMessageA #endif #endif
So to conclude and keep in mind a good rules to prevent that kind of naming conflict or collision, I would just advice follow a simple convention no ‘full’ uppercase in identifier name (function, variable, enum, etc….) see google coding style