C++ Preprocessor metaprogramming: obtaining an unique value?
c++, c-preprocessor, lua, metaprogramming
Solution
You need to add an extra layer of macros to make the preprocessor do the right thing:
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define LUA_GLOBAL(lua_name, c_name) ... TOKENPASTE2(_luaGlobal, __LINE__) ...
Some compilers also support the `__COUNTER__` macro, which expands to a new, unique integer every time it is evaluated, so you can use that in place of `__LINE__` to generate unique identifiers. I'm not sure if it's valid ISO C, although gcc accepts its use with the `-ansi -pedantic` options.
Problem
I'm exploiting the behavior of the constructors of C++ global variables to run code at startup in a simple manner. It's a very easy concept but a little difficult to explain so let me just paste the code: ``` struct _LuaVariableRegistration { template<class T> _LuaVariableRegistration(const char* lua_name, const T& c_name) { /* ... This code will be ran at startup; it temporarily saves lua_name and c_name in a std::map and when Lua is loaded it will register all temporarily global variables in Lua. */ } }; ``` However manually instantiating that super ugly class every time one wants to register a Lua global variable is cumbersome; that's why I created the following macro: ``` #define LUA_GLOBAL(lua_name, c_name) static Snow::_LuaVariableRegistration _____LuaGlobal ## c_name (lua_name, c_name); ``` So all you have to do is put that in the global scope of a cpp file and everything works perfectly: ``` LUA_GLOBAL("LuaIsCool", true); ``` There you go! Now in Lua `LuaIsCool` will be a variable initialized to true! But, here is the problem: ``` LUA_GLOBAL("ACCESS_NONE", Access::None); ``` Which becomes: ``` static Snow::_LuaVariableRegistration _____LuaGlobalAccess::None ("ACCESS_NONE", &Access::None); ``` :(( I need to concatenate `c_name` in the macro or it will complain about two variables with the same name; I tried replacing it with `__LINE__` but it actually becomes `_____LuaGlobalAccess__LINE__` (ie it doesn't get replaced). So, is there a way to somehow obtain an unique string, or any other workaround? PS: Yes I know names that begin with _ are reserved; I use them anyway for purposes like this being careful to pick names that the standard library is extremely unlikely to ever use. Additionally they are in a namespace.