I am having trouble with the preprocessor token pasting operator in gcc 4.7.1 (std=c++11). Namely, consider the following code:
// Create a name for a global map (this works)
#define GLOBAL_MAP(name) g_map_ ## name // This works fine
// Now, namespace qualify this map (this fails to compile when used)
#define NS_QUAL_GLOBAL_MAP(name) SomeNamespace:: ## GLOBAL_MAP(name)
Usage scenarios - first the map definitions:
std::map<std::string,std::string> GLOBAL_MAP(my_map);
namespace SomeNamespace
{
std::map<std::string,std::string> GLOBAL_MAP(my_map);
}
Now the usage:
void foo()
{
bar(GLOBAL_MAP(my_map)); // This compiles fine
baz(NS_QUAL_GLOBAL_MAP(my_map)); // This fails to compile with:
// error: pasting "::" and "NAME_MAP" does not give a
// valid preprocessing token
}
What I believe might be happening is that it is interpreting GLOBAL_MAP
after ##
as a token for pasting rather than a macro to be further expanded. How do I get around this?
Token-pasting operator (##)Allows tokens used as actual arguments to be concatenated to form other tokens. It is often useful to merge two tokens into one while expanding macros. This is called token pasting or token concatenation. The '##' pre-processing operator performs token pasting.
## is usued to concatenate two macros in c-preprocessor.
The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.
Concatenation involves appending one string to the end of another string. For example, say we have two strings: “C programming” and “language”. We can use concatenation to generate the output, “C programming language.”
Token pasting generates a single token for the compiler to read. This isn’t what you want here — ::
is a valid C++ token on its own, but ::g_map_my_map
isn’t a token that the compiler knows.
Hence, remove the token pasting operator:
#define NS_QUAL_GLOBAL_MAP(type) SomeNamespace::GLOBAL_MAP(type)
You don't need the ##
operator after ::
. The ##
operator is used to form a single token, but SomeNamespace::g_map_mymap
are multiple tokens anyway. Just do
#define NS_QUAL_GLOBAL_MAP(type) SomeNamespace::GLOBAL_MAP(type)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With