This question already has answers here:
C preprocessor: stringize macro and identity macro
(2 answers)
What does #x inside a C macro mean?
(4 answers)
How can I concatenate twice with the C preprocessor and expand a macro as in "arg ## _ ## MACRO"?
(3 answers)
Closed 6 years ago.
Please explain the code
#include <stdio.h>
#define A(a,b) a##b
#define B(a) #a
#define C(a) B(a)
main()
{
printf("%s\n",C(A(1,2)));
printf("%s\n",B(A(1,2)));
}
Output
12
A(1,2)
I don't understand, how the first printf evaluates to 12?
Isn't it similar to the second, as C macro is simply a wrapper to B macro?
As mentioned in Wikipedia in C-preprocessor :
The ## operator (known as the "Token Pasting Operator") concatenates
two tokens into one token.
The # operator (known as the "Stringification Operator") converts a
token into a string, escaping any quotes or backslashes appropriately.
If you want to stringify the expansion of a macro argument, you have
to use two levels of macros:
You cannot combine a macro argument with additional text and stringify
it all together. You can however write a series of adjacent string
constants and stringified arguments: the C compiler will then combine
all the adjacent string constants into one long string.
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo) // outputs "foo"
xstr (foo) // outputs "4"
Also, from C-FAQ Question 11.17 :
It turns out that the definition of # says that it's supposed to
stringize a macro argument immediately, without further expanding it
(if the argument happens to be the name of another macro).
So, similarly, going along these lines :
you're doing C(A(1,2)),
which would roll to C(12), // since no #, so inner argument is expanded
and then to B(12)
// [since you've done two levels of macros in the code:
// 1. from C() to B(), and then, 2. B() to #a]
= 12 .
Whereas, in the first case, only 1 level of stringification is plainly done as per definition of B(a)(since it gets stringified immediately because of #)
macro-replacement of B(A(1,2))
= stringification of A(1,2)
= A(1,2).
The confusion here comes from a simple rule.
When evaluating a macro the pre-processor first resolves the macros in the arguments passed to the macro. However, as a special case, if an argument is right of # or adjacent to ##, it doesn't resolve macros within such arguments. Such are the rules.
Your first case
C(A(1,2))
The pre-processor first applies the C(a) macro, which is defined as B(a). There's no # or ## adjacent to the argument in the definition (none of them in B(a) at all), thus the pre-processor must resolve macros in the argument:
A(1,2)
The definition of A(a,b) is a##b which evaluates into 12.
After the macros in the arguments of the C(a) macro are evaluated, the C macro becomes:
C(12)
The pre-processor now resolves the C(a) macro, which according to its definition becomes
B(12)
Once this is done, the pre-processor evaluates macros inside the result once again and applies the B(a) macro, so the result becomes
"12"
Your second case
B(A(1,2))
Similar to the first case, the pre-processor first applies the B(a) macro. But this time, the definition of the macro is such that the argument is preceded by #. Therefore, the special rule applies and macros inside the argument are not evaluated. Therefore, the result immediately becomes:
"A(1,2)"
The preprocessor goes over the result again trying to find more macros to expand, but now everything is a part of the string, and macros don't get expanded within strings. So the final result is:
"A(1,2)"
C preprocessor has two operators # and ##. The # operator turns the argument of a function like macro to a quoted string where ## operator concatenates two identifiers.
#define A(a,b) a##b will concatenate a with b returning ab as string.
so A(1,2) will return 12
#define B(a) #a will return a as string
#define C(a) B(a) will call previous one and return a as string.
so C(A(1,2)) = C(12) = B(12) = 12 (as string)
B(A(1,2)) = A(1,2) because A(1,2) is taken as an argument and returned as string A(1,2)
There are two operators used in the function-like macros:
## causes a macro to concatenate two parameters.
# causes the input to be effectively turned into a string literal.
In A(a,b) ## causes a to be concatenated with b. In B(a), # effectively creates a string literal from the input. So the expansion runs as follows:
C(A(1,2)) -> C(12) -> B(12) -> "12"
B(A(1,2)) -> "A(1,2)"
Because for C(A(1,2)), the A(1,2) part is evaluated first to turn into 12, the two statements aren't equal like they would appear to be.
You can read more about these at cppreference.
Related
I would like to pass 2 arguments to a macro using another macro:
#define A_AND_B 5,1
#define ADD(a, b) a + b
int add_them(void)
{
int result = ADD(A_AND_B);
return result ;
}
I would hope that expands to
int result = 5 + 1;
and I get 6. Instead I get
Error 'ADD' undeclared (first use in this function)
Error macro "ADD" requires 2 arguments, but only 1 given
Is there a way around this?
As is often the case, you need an extra level of (macro) indirection:
#define A_AND_B 5,1
#define ADD(...) ADD_(__VA_ARGS__)
#define ADD_(a, b) a + b
int add_them(void)
{
int result = ADD(A_AND_B);
return result ;
}
ADD is defined as variadic so that it will work as either ADD(A_AND_B) or ADD(A, B).
This works because __VA_ARGS__ in the replacement body of ADD is replaced with the actual arguments before the replacement body is scanned for macros.
Per C 2018 6.10.3.1, a compiler first identifies the arguments for a function-like macro and then performs macro replacement on the arguments, followed by macro replacement for the function-like macro. This means that, in ADD(A_AND_B), the argument is identified as A_AND_B before it is replaced with 5,1. As the macro invocation has only this single argument and the macro is defined to have two parameters, an error is diagnosed.
Given your definition of ADD, there is no way to change this behavior in a compiler that conforms to the C standard.
You can instead use another macro to expand the arguments and apply the desired macro:
#define Apply(Macro, Arguments) Macro(Arguments)
then int result = Apply(ADD, A_AND_B); will work. That will identify ADD and A_AND_B as arguments to Apply. Then it will expand those, producing an unchanged ADD and 5,1. Then the macro replacement for Apply produces ADD(5,1). Then this is again processed for macro replacement, which replaces ADD(5,1) in the ordinary way.
Note that good practice is usually to define ADD as #define ADD(a, b) ((a) + (b)) to avoid unexpected interactions with other operators neighboring the use of the macro.
I have a macro, SOME_MACRO. It takes an argument.
Definition of SOME_MACRO:
#define SOME_MACRO(arg) __SOME_MACRO(arg)
Further I want __SOME_MACRO(arg) to expand to "ABC" if arg is 0. And if arg is not zero, __SOME_MACRO(arg) should expand to "DEF"
Suppose I call with argument 0, that is: SOME_MACRO(0)
I need to test at preprocessing time, whether the argument is zero or not.
#if <argument is zero> // line 1
#define __SOME_MACRO(arg) "ABC"
#elif
#define __SOME_MACRO(arg) "DEF"
#endif
My question is: What should be at line 1?
Taking an example:
SOME_MACRO(2) should expand to "DEF"
SOME_MACRO(0) should expand to "ABC"
Here is a solution for the requested behavior. Do not use it, it is bad practice, and you should not be attempting this.
/* Define __SOME_MACRO:
Defer is used so that its arguments will be macro-replaced before
Kludge is processed.
"Kludge" is pasted to arg. If this makes "Kludge0", it will be
replaced by two arguments (an empty argument, a comma, and the argument
"abc"). Otherwise, if it forms a single token, that is one argument.
(If the pasting does not form a proper token, the behavior is
undefined. Most likely, the compiler will report an error.)
The resulting argument(s) are then passed to Kludge, followed by "DEF".
Kludge is replaced by its second argument. If __SOME_MACRO's argument
was "0", this second argument is "ABC". Otherwise, it is "DEF".
*/
#define Kludge0 , "ABC"
#define Kludge(x, y,...) y
#define Defer(x, ...) Kludge(x, __VA_ARGS__)
#define __SOME_MACRO(arg) Defer(Kludge##arg, "DEF",)
__SOME_MACRO(0)
__SOME_MACRO(2)
This is not possible. The expression given to #if is only evaluated once, at the line where #if is encountered. There is no way to have it evaluated again each time you invoke your macro.
As Eric Postpischil says, C does not have any general way to make the expansion of a macro conditional on its arguments.
A couple of possible alternatives:
Use an expression with the ternary ?: operator, as pmg suggested in a comment:
#define __SOME_MACRO(arg) ((arg) ? "DEF" : "ABC")
Then SOME_MACRO(0) will expand to ((0) ? "DEF" : "ABC"). Any reasonable compiler will notice that the condition is a constant, and compile this just as if you had only written "ABC"; it should not generate code for a test nor for the unreachable branch. Conditionals with the ternary operator can even be used in expressions that must be compile-time constants, as long as the condition is itself a compile-time constant; e.g. __SOME_MACRO(0) can be used to initialize a global or static variable.
Of course this will not work if the desired expansion is not syntactically an expression, e.g. if you are trying to use your macro to create declarations or definitions or something more syntactically elaborate.
If you know that only a small set of possible arguments will be used, you could use token pasting with the ## operator to expand the macro as one of another set of macros:
#define __SOME_MACRO_0 "ABC"
#define __SOME_MACRO_1 "DEF"
#define __SOME_MACRO_2 "DEF"
#define __SOME_MACRO(arg) __SOME_MACRO_ ## arg
Then __SOME_MACRO(0) expands to "ABC" and __SOME_MACRO(2) expands to "DEF". However __SOME_MACRO(3) will not compile unless you write a corresponding __SOME_MACRO_3 macro, and __SOME_MACRO(0+1) cannot be made to work at all, at least not in any way that I know of.
(As written, __SOME_MACRO(0+1) expands to "ABC"+1, which is equivalent to "BC" and will probably cause you a lot of confusion before you figure out what is wrong. __SOME_MACRO(1-1) is even worse...)
Also, #define ZERO 0 followed by __SOME_MACRO(ZERO) doesn't work as it stands, thought it can be fixed by doing
#define SECOND_MACRO(arg) __SOME_MACRO_ # arg
#define __SOME_MACRO(arg) SECOND_MACRO(arg)
I want to create parameterized preprocessor macro for IBM Metal C Prolog.
The initial unparametrized form is
#pragma prolog(Foo, " #MCPROLG MAIN=(YES,16,132)")
The real prolog is more complex, but for the sake of the question the important part is that there are values within a string.
#pragma directive itself can't be part of a macro, so I replace that with _Pragmalike that:
_Pragma("prolog(Foo, \" #MCPROLG MAIN=(YES,16,132)\")")
I can parameterize Foo like this:
#define STR(...) #__VA_ARGS__
#define PROLOG(function) _Pragma(STR(prolog( function , " #MCPROLG MAIN=(YES,16,132)")))
How can I create macro that parameterizes the value 16?
It appears that I need to concatenate strings within preprocessor, I've tried following approaches. All use this stringization macro:
#define STR(...) #__VA_ARGS__
Token that is replaced with 16 (let's name it size) can't be within a string itself so that it is replaced.
#define PROLOG(function, size) _Pragma(STR(prolog( function , " #MCPROLG MAIN=(YES, size ,132)")))
_Pragma only accepts a single string, so I can't peruse C string concatenation like this:
#define PROLOG(function, size) _Pragma(STR(prolog( function , " #MCPROLG MAIN=(YES," #size ",132)")))
I can't stringize the whole second argument of prolog like this:
#define PROLOG(function, size) _Pragma(STR(prolog( function , STR( #MCPROLG MAIN=(YES, size ,132)))))
because #MCPROLG needs to stay within a string so that its # is not treated as stringization token.
To address issue 1 (need to expand a parameter in the replacement list), you need an indirect stringify macro:
#define STR(X) STR_I(X)
#define STR_I(X) #X
You may make this variadic if you want but it's not necessary here (the commas in your string are surrounded by parentheses; the preprocessor will match those; e.g., FOO(A=(B,C,D)), given FOO is a function-like macro, has one argument).
To address issue 2, yes, you need to stringify the whole thing. Effectively there's no such thing as string literal concatenation to the preprocessor (because it runs in translation phase 4, and string literal concatenation doesn't happen until translation phase 6).
To address issue 3, just produce a hash from another macro (root it at an object-like macro, where # has no special meaning):
#define HASH #
#define HASHM() HASH
The function-like variant allows you to produce the same hash right next to something else (HASHMCPROLG does nothing useful; HASH MCPROLG produces # MCPROLG, HASHM()MCPROLG produces #MCPROLG).
Those pieces in hand, the rest is easy:
#define PROLOG(FN_,SZ_) _Pragma(STR(prolog(FN_, STR( HASHM()MCPROLG MAIN=(YES,SZ_,132)))))
Here I'm assuming you also need an end parentheses around the pragma prolog and that in the question this was a typo; that is, it should be:
_Pragma("prolog(foo, \"#MCPROLG MAIN=(YES,16,132)\")")
...not:
_Pragma("prolog(foo, \"#MCPROLG MAIN=(YES,16,132)\"")
From The C Programming Language, by KRC
After
#define cat(x, y) x ## y
the call cat(var, 123) yields var123. However, the call
cat(cat(1,2),3) is undefined: the presence of ## prevents
the arguments of the outer call from being expanded. Thus it
produces the token string cat ( 1 , 2 )3
and )3 (the catenation of the last token of the first argument with
the first token of the second) is not a legal token.
If a second level of macro definition is introduced,
#define xcat(x, y) cat(x,y)
things work more smoothly; xcat(xcat(1, 2), 3) does produce
123, because the expansion of xcat itself does not involve the
## operator.
What is the property of ## that makes the difference between the two examples?
Why is the inner cat(1,2) in the first example not expanded, while the inner xcat(1,2) in the second example is?
Thanks!
It is one of the (not-so-well-known) characteristics of the macro ## operator that it inhibits further expansion of its arguments (it just considers them plain strings). An excerpt from the gcc pre-processor docs:
...As with stringification, the actual argument is not macro-expanded first...
That is, arguments to ## are not expanded.
By implementing the additional indirection using your xcat macro you are working around the problem (A process that is called the argument prescan is jumping in and actually evaluates the resulting string twice)
This is a very simplified version of some code I just ran into at work:
#include <stdio.h>
#define F(G) G(1)
#define G(x) x+1
int main() {
printf("%d\n", F(G));
}
prints 2.
Now, I can see that F(G) expands to G(1) and then G(1) expands to 2, but its not clear to me why. I would have expected to get an error that G is not a function from the printf line.
How does the pre-processor parse code like this?
A function-like macro is only invoked if its name is followed by a (.
In F(G), G is not followed by a (, so the G there is not a macro invocation.
In F(G) G(1), G is a macro parameter and thus is not macro-replaced directly (this is a very confusing macro you've got :-O). In G(1), G is replaced by the argument corresponding to the parameter G, which also happens to be G. That replacement is then rescanned and G(1) is evaluated to 1 + 1.
If we rewrite your macros so that you aren't using G in multiple different ways, it's far easier to understand:
#define F(x) x(1)
#define G(x) x + 1
Here, F(G) is replaced by G(1). This is then rescanned, and the invocation of G is evaluated, yielding 1 + 1.
Expanding on James McNellis' answer, the C99 standard prescribes:
6.10.3.4 Rescanning and further replacement
1 After all parameters in the replacement list have been substituted and # and ##
processing has taken place, all placemarker preprocessing tokens are removed. Then, the
resulting preprocessing token sequence is rescanned, along with all subsequent
preprocessing tokens of the source file, for more macro names to replace.
2 If the name of the macro being replaced is found during this scan of the replacement list
(not including the rest of the source file’s preprocessing tokens), it is not replaced.
Furthermore, if any nested replacements encounter the name of the macro being replaced,
it is not replaced. These nonreplaced macro name preprocessing tokens are no longer
available for further replacement even if they are later (re)examined in contexts in which
that macro name preprocessing token would otherwise have been replaced.
3 The resulting completely macro-replaced preprocessing token sequence is not processed
as a preprocessing directive even if it resembles one, but all pragma unary operator
expressions within it are then processed as specified in 6.10.9 below.
#defines do very basic string replacement:
printf("%d\n", F(G));
goes to
printf("%d\n", G(1));
which goes to:
printf("%d\n", 1+1);
The preprocessor makes one pass, but you are thinking that it makes one pass per #define. So during its pass the preprocessor matches and replaces F(G) but doesn't match any G(x).