Concatenation of two definition - c

#define ID proj1
#define PROJ ID##_data.h
As per my requirements definition of PROJ should have proj1_data.h
When I print PROJ It should give proj1_data.h ,
Please help me to get the desired result. Thanks in advance !

You can only print a string. So to print PROJ, you would need to turn it into a string.
#define STRINGIZE(X) #X
#define STRINGIZE2(X) STRINGIZE(X)
STRINGIZE applies the stringizing operator on the argument. It turns the argument into a string, essentially by surrounding it with quotation marks, and escaping the contents as necessary to create a valid string. STRINGIZE2 is used to allow the argument to be expanded by the preprocessor before it is turned into a string. This is useful when you want to stringize the expansion of a macro instead of the macro itself. For example STRINGIZE2(__LINE__) will result in a string that represents the current line in the file, e.g. "1723". However, STRINGIZE(__LINE__) results in the string "__LINE__".
Your definition of PROJ faces a similar issue. It actually results in the token ID_data..h rather than proj1_data.h. You need a level of expansion indirection to allow ID to expand before you concatenate.
#define PASTE(X, Y) X ## Y
#define MKFILE(X) PASTE(X, _data.h)
#define PROJ STINGIZE2(MKFILE(ID))
Using STRINGIZE2 allows the MKFILE invocation to expand. Allowing MKFILE to invoke PASTE allows the ID token to expand.

Related

Using '#' and '##' preprocessing operators together

From what I have read I understand that # operator is used with a parametric macro to convert it's parameter to a string and ## is used to join two parameters or a parameter with some other identifier (Correct me if my understanding is wrong).
But how can I use both # and ## operator together? I tried it by doing:
#define str(n) #n ## #n
I thought then
printf("%s",str(Hello))
will be expanded as
printf("%s", "Hello""Hello")
And as adjacent strings are joined automatically to make one string in C so, this will lead to printf("%s", "HelloHello") and output will beHelloHello. But the story was different, it throws an error:
pasting "hello" and "hello" does not give a valid preprocessing token
Please explain me how these parametric macros with # and ## operator are expanded.
## "joining two parameters" is a vast oversimplification. This operator joins tokens. And the result must be a single valid token. Two string literal tokens cannot be token pasted into a single token.
Furthermore, string literal concatenation is handled at a later translation phase. So an obvious fix to your macro is to not use ## at all.
#define str(n) #n #n
But if you really want to use both, then you need to token paste before stringifying. And do that via an intermediate macro expansion.
#define str(n) str_(n ## n)
#define str_(nn) #nn

How to parametrize single string containing # in C preprocessor?

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)\"")

Confusion about C macro expansion in enum

I see below code snippet in fwts code base:
#define FWTS_CONCAT(a, b) a ## b
#define FWTS_CONCAT_EXPAND(a,b) FWTS_CONCAT(a, b)
#define FWTS_ASSERT(e, m) \
enum { FWTS_CONCAT_EXPAND(FWTS_ASSERT_ ## m ## _in_line_, __LINE__) = 1 / !!(e) }
#define FWTS_REGISTER_FEATURES(name, ops, priority, flags, features) \
/* Ensure name is not too long */ \
FWTS_ASSERT(FWTS_ARRAY_LEN(name) < 16, \
fwts_register_name_too_long);
My questions are:
For the definition of FWTS_ASSERT(e, m), I know the !! can convert whatever value into 1 or 0. But doesn't it cause error for FWTS_ASSERT() when !!(e) evaluates to 0 thus leads to 1/0 ?
And btw, the FWTS_CONCAT_EXPAND(a,b) and FWTS_CONCAT(a, b) seem to be duplicated, why do we need 2 of them?
ADD 1
Based on #Klas Lindbäck's answer, I want to go through the macro expansion with a concrete example.
Suppose I have:
#define M_1 abc
#define M_2 123
Then I guess the expansion process of FWTS_CONCAT_EXPAND(M_1,M_2) should be:
FWTS_CONCAT_EXPAND(M_1,M_2)
->
FWTS_CONCAT(abc, 123)
->
abc123
If I directly applying FWTS_CONCAT(M_1, M_2), will it be expanded like this?
FWTS_CONCAT(M_1, M_2)
->
M_1M_2
->
Bang! M_1M_2 is an invalid symbol!
(Please correct me if I am wrong...)
ADD 2
Tried with gcc -E macroTest.c -o macroTest.i:
(macroTest.c)
#define M_1 abc
#define M_2 123
#define FWTS_CONCAT(a, b) a ## b
#define FWTS_CONCAT_EXPAND(a,b) FWTS_CONCAT(a, b)
FWTS_CONCAT_EXPAND(M_1, M_2)
FWTS_CONCAT(M_1,M_2)
(macroTest.i)
# 1 "macroTest.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "macroTest.c"
abc123
M_1M_2
I think I get the point of the macro expansion rule. Below are some related concepts and quotation:
Argument Prescan:
Macro arguments are completely macro-expanded before they are
substituted into a macro body, unless they are stringified or pasted
with other tokens. After substitution, the entire macro body,
including the substituted arguments, is scanned again for macros to be
expanded. The result is that the arguments are scanned twice to expand
macro calls in them.
Stringification
When a macro parameter is used with a leading ‘#’, the preprocessor
replaces it with the literal text of the actual argument, converted to
a string constant.
Token Pasting / Token Concatenation:
It is often useful to merge two tokens into one while expanding
macros. This is called token pasting or token concatenation. The ‘##’
preprocessing operator performs token pasting. When a macro is
expanded, the two tokens on either side of each ‘##’ operator are
combined into a single token, which then replaces the ‘##’ and the two
original tokens in the macro expansion.
So the detailed process of my scenario is like this:
FWTS_CONCAT_EXPAND(M_1, M_2)
-> FWTS_CONCAT_EXPAND(abc, 123) // M_1, M_2 pre-expanded since FWTS_CONCAT_EXPAND has no ##.
-> FWTS_CONCAT(abc, 123) // FWTS_CONCAT_EXPAND expanded into FWTS_CONCAT
-> abc123 // FWTS_CONCAT expanded
FWTS_CONCAT(M_1,M_2)
-> M_1M_2 //M_1, M_2 are not pre-expanded because of the ## in FWTS_CONCAT
-> DEADEND
The macros are used for compile time checking. This is useful when you write code that will be compiled and run on many different platforms and where some platforms may not be compatible.
If the first parameter to FWTS_ASSERT evaluates to non-zero (true) then !!(e) will evaluate to 1 and the enum will be created with the name FWTS_ASSERT_<second parameter>_in_line_<line>. I suspect that the enum is never actually used.
If the first parameter to FWTS_ASSERT evaluates to 0 (= false) then the compiler will try to compute 1/0 and generate a compiler error where it will hopefully tell which enum member caused the error, in this case FWTS_ASSERT_fwts_register_name_to_long_in_line_4.
And btw, the FWTS_CONCAT_EXPAND(a,b) and FWTS_CONCAT(a, b) seem to be duplicated, why do we need 2 of them?
FTW_CONCAT_EXPAND is done in 2 steps because we want to first expand any macros in the parameters and then perform the concatenation. Doing it in two steps makes the preprocessor do macro expansion of the parameters before it does the string concatenation.

Use of # in a macro [duplicate]

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.

C language macro code - #define with 2 '##'

I recently came across this question and could not find supporting document or data in explanation. The question was asked to me and the person was not willing to share the answer.
#define BIT(A) BIT_##A
#define PIN_0 0
"Do we get BIT_0 by using macro BIT(PIN_0)? If no make necessary corrections?"
I dont know the answer to the above question?
The macro
#define BIT(A) BIT_##A
means to create a single token from what would otherwise be two separate tokens. Without using ## (the token concatenation operator), you might be tempted to do one of:
#define BIT(A) BIT_A
#define BIT(A) BIT_ A
The problem with the first is that, because BIT_A is already a single token, no attempt to match the A to the passed argument will succeed, and you'll get the literal expansion BIT_A no matter what you've used as an argument:
BIT(42) -> BIT_A
The problem with the second is that, even though A is a separate token and will therefore be subject to replacement, the final expansion will not be a single token:
BIT(42) -> BIT_ 42
The ## in your macro takes the value specified by A, and appends it to the literal BIT_ forming one token so, for example,
BIT(7) -> BIT_7
BIT(PIN0) -> BIT_PIN0, but see below if you want BIT_0
This is covered in C11 6.10.3.3 The ## operator:
... each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing
token is concatenated with the following preprocessing token.
The resulting token is available for further macro replacement.
Now, if you want a macro that will concatenate together BIT_ and another already-evaluated macro into a single token, you have to use some trickery to get it to do the initial macro substitution before the concatenation.
That's because the standard states that the concatenation is performed before regular macro replacement, which is why this trickery is needed. The problem with what you have:
#define PIN_0 0
#define BIT(A) BIT_##A
is that the ## expansion of BIT(PIN0) will initially result in the single token BIT_PIN0. Now, although that's subject to further macro replacement, that single token doesn't actually have a macro replacement, so it's left as is.
To get around this, you have to use levels of indirection to coerce the preprocessor into doing regular macro replacement before ##:
#define CONCAT(x,y) x ## y
#define PIN0 0
#define BIT(A) CONCAT(BIT_,A)
This series of macros shown above goes through a number of stages:
BIT(PIN0)
-> CONCAT(BIT_,PIN0)
-> CONCAT(BIT_,0)
-> BIT_0

Resources