Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C preprocessor tokenization does not expand macro?

1) Why is the macro MSG not expanded in the following expression?

#define MSG Hello
#define HELLO(name)  MSG ## name

void HELLO(Dave) () {}

Using

gcc -E -P test.cpp 

Output:

void MSGDave () {}

MSG name expands to Hello Dave. And MSG # name expands to Hello "Dave". So what causes gcc not to expand MSG ## name?

2) Is there a workaround?

Is there a preprocessor directive like defined(x), such as expand(x)?

like image 899
Brent Faust Avatar asked Mar 13 '14 04:03

Brent Faust


People also ask

How are macros expanded in C?

The LENGTH and BREADTH are called the macro templates. The values 10 and 20 are called macro expansions. When the program run and if the C preprocessor sees an instance of a macro within the program code, it will do the macro expansion. It replaces the macro template with the value of macro expansion.

What is preprocessor expansion?

The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control. In many C implementations, it is a separate program invoked by the compiler as the first part of translation.

What is a preprocessor token?

Preprocessing tokens (pp-tokens) are a superset of regular tokens. Preprocessing tokens allow the source file to contain non-token character sequences that constitute valid preprocessing tokens during translation. There are four categories of preprocessing tokens: Header filenames, meant to be taken as a single token.


2 Answers

Because macro arguments are not substituted when preceded or followed by a ## operator.

C11 §6.10.3.1 Argument substitution

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

like image 80
Yu Hao Avatar answered Oct 05 '22 03:10

Yu Hao


#define MSG Hello
#define cat(x, y) x ## y
#define cat2(x, y) cat(x, y)
#define HELLO(name) cat2(MSG,name)

Live demo @ ideone.

like image 21
n. 1.8e9-where's-my-share m. Avatar answered Oct 05 '22 03:10

n. 1.8e9-where's-my-share m.