Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ preprocessor token pasting for namespace qualification

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?

like image 925
Michael Goldshteyn Avatar asked Aug 27 '15 14:08

Michael Goldshteyn


People also ask

What is token pasting operator in C?

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.

What does ## mean in C language?

## is usued to concatenate two macros in c-preprocessor.

What does ## mean?

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.

What is concatenation operator in embedded C?

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.”


2 Answers

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)
like image 164
Konrad Rudolph Avatar answered Sep 22 '22 18:09

Konrad Rudolph


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)
like image 42
ex-bart Avatar answered Sep 24 '22 18:09

ex-bart