Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the indirection needed [duplicate]

Consider the following macro:

#define CAT(X, Y) X ## Y
#define CMB(A, B) CAT(A, B)
#define SLB_LOGGING_ALGORITHM CMB(Logging, SLB_ALGORITHM)

where SLB_ALGORITHM is a defined pre-processor symbol.

If I just use CAT directly instead of CMB, SLB_ALGORITHM does not get expanded. Why is that the case and how exactly does the indirection help?

like image 560
AlwaysLearning Avatar asked May 08 '16 12:05

AlwaysLearning


2 Answers

## is a string concatenator, so if you call CAT(Logging, SLB_ALGORITHM) from SLB_LOGGING_ALGORITHM macro, this will result in concatenation of string Logging with string SLB_ALGORITHM, that is: LoggingSLB_ALGORITHM which is likely not what you want.

When calling CMB(Logging, SLB_ALGORITHM) from SLB_LOGGING_ALGORITHM macro, instead, preprocessor first expands Logging and SLB_ALGORITHM (call to CMB()) then concatenate the expanded strings (call to CAT()).

like image 169
shrike Avatar answered Oct 31 '22 23:10

shrike


To quote this answer:

When you have a macro replacement, the preprocessor will only expand the macros recursively if neither the stringizing operator # nor the token-pasting operator ## are applied to it.

So the preprocessor does not expand a given macro when ## is applied to it. This is why it is exapnded in the CMB(A, B) level but not when directly using CAT(X, Y) .

like image 45
Tomer Avatar answered Oct 31 '22 22:10

Tomer