What this trick is? [duplicate] - c

This question already has an answer here:
C preprocessor # and ## operators
(1 answer)
Closed 9 years ago.
#include <stdio.h>
#define PRINT(name) print ## name()
void printHE()
{
printf("Hello");
}
void printWO()
{
printf("World\n");
}
enum {
HE,
WO,
};
int main()
{
PRINT(HE);
PRINT(WO);
}
It works perfectly, but why?
What does ## in #define mean?
And why HE didn't convert to 0 ?

Given that you're asking about ## I am assuming that PRINT is defined as
#define PRINT(X) print##X()
The ## is a token-pasting operator, it connects two tokens to its left and to its right together, producing a single token.
When you write PRINT(HE), preprocessor converts that to printHE(), which is a regular function call.
since HE is a enum, should HE translate to 0
That's a very good question! The translation does not happen, because preprocessor runs before enums are interpreted, so the fact that HE and WO are enum members does not change anything.

It is the escape sequence in your expression. It concatenates the leftmost and the rightmost to produce the token.
## is token pasting operator

In #define PRINT(name) print ## name
## is token pasting operator, used to "glue" tokens together

On my computer, it doesn't work right. Print error like below:
two_sharp.c:(.text+0x3a): undefined reference to PRINT'
two_sharp.c:(.text+0x46): undefined reference toPRINT'
collect2: ld returned 1 exit status

Related

How ## operator in macro works?

I was studying some macro operations, and I got this Code and I was unable to figure out how this code is actually working and generates the output? and is there any (i-+) operator that exists or not?
Here is the code
#include<stdio.h>
#define p(a,b) a##b
#define call(x) #x
int main()
{
do{ int i=14,j=3;
printf("%d",p(i-+,+j));
}while(*(call(625)+3));
return 0;
}
Output is 10.
It will be very helpful if you explain it with some examples.
The ## in the macro is the concatenation operator, it glues its operands together. So after the preprocessor is done, that expression will be
i-++j
which of course just means i - (++j), i.e. 14 - 4 which of course is 10.

Why doesn’t the preprocessor cause two adjacent minus signs to be a decrement? [duplicate]

This question already has answers here:
strange result on macro expansion
(4 answers)
Closed 5 years ago.
Consider the following code:
#include <stdio.h>
#define A -B
#define B -C
#define C 5
int main()
{
printf("The value of A is %d\n", A);
return 0;
}
Here preprocessing should take place in the following manner:
first A should get replaced with -B
then B should get replaced with -C thus expression resulting into --C
then C should get replaced with 5 thus expression resulting into --5
So the resultant expression should give a compilation error( lvalue error ).
But the correct answer is 5, how can the output be 5?
Please help me in this.
It preprocesses to (note the space):
int main()
{
printf("The value of A is %d\n", - -5);
return 0;
}
The preprocessor pastes tokens, not strings. It won't create -- out of two adjacent - tokens unless you force token concatenation with ##:
#define CAT_(A,B) A##B
#define CAT(A,B) CAT_(A,B)
#define A CAT(-,B)
#define B -C
#define C 5
int main()
{
printf("The value of A is %d\n", A); /* A is --5 here—no space */
return 0;
}
Although the C preprocessor often feels like it’s literally doing a search and replace on the code, the preprocessor actually works a bit differently.
Before the preprocessor runs, the source file is split into preprocessing tokens, which are individual units of text. For example, a single minus sign is treated not as a character, but as a token consisting of a minus sign, and a double minus sign is treated as a token consisting of two minus sign.
The C preprocessor kicks in and replaces each macro not with the literal text of the macro replacement, but rather with the series of preprocessor tokens in that replacement. In this case, the preprocessor replaces A with a minus followed by B, then replaces B with a minus followed by C, then replaces C with 5. The effect here is that there are two unary minuses applied to the 5, rather than a decrement operator, even though a literal search and replace would have generated a decrement operator that produces a syntax error.
This is interesting in that there’s no way you can write two consecutive minus signs in source code and have it interpreted as two unary minuses. This only works because by the time the preprocessor splices everything together, it already knows it’s looking at two unary minuses. The resulting C code isn’t then rescanned to be tokenized a second time around.
Now the legalese: section §5.1.1.2/7 says that after macro substitution is done, each preprocessing token - and here there are two of them (the two minus signs) - are converted into actual tokens, and then they’re syntactically and semantically analyzed. That means that there’s no opportunity for the compiler to rescan those tokens to reinterpret them as a single token. So this is a weird case where the resulting token stream can’t actually be typed into the source code without changing the meaning.
Think of the resultant expression as this instead:
-(-(5))

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.

#define directive in C Giving ambiguous answer [duplicate]

This question already has answers here:
C : #define usage [duplicate]
(3 answers)
Closed 7 years ago.
#include <stdio.h>
#define SQR(x) x*x
int main()
{
printf("%d",225/SQR(15));
return 0;
}
The output to this code is 225. I'm unable to understand as what really is happening here.
If I use #define SQR(x) (x*x) Then it works fine which i get as we are supposed to use parentheses if we have an expression with some operator.
But in the previous case I'm not clear as to what is really happening. Why is the answer 225?
#define macros aren't functions - they are just macros, text replacement. If you take the expression 225/SQR(15) and replace SQR with 15*15, you'll get 225/15*15, and since / and * have the save precedence and are left associative - 255/15*15 = 255.
Macros do substitution only(done before compilation of the code).
Therefore the following line
printf("%d",225/SQR(15));
after substitution will become:
printf("%d",225/15*15);
now this expression evaluates to 225 (basic maths : divide first -> 15*15, then multiply -> 225)
using brackets solves your problem(then it becomes 225/(15*15)).
:)
Notice the steps
1) 225/SQR(15)
2) 225/15*15
Division executed first due to precedence
3) 15*15
4) 225
See #define as a text replacement tool in a text editor; it works the same way (well, almost).
Here are two rules you might want to follow in order to avoid this kind of errors:
When working with macros, always use parentheses for each "variable" given to the macro and for the whole result.
Example:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
When you have an unexpected behavior, use the command line tool cpp (c preprocessor) to see how the macro is actually interpreted.
Example:
$ cpp main.c

Macro output explanation

When I run the following code,
#include<stdio.h>
#define X (4+Y)
#define Y (X+3)
int main()
{
printf("%d",4*X+2);
return 0;
}
I am getting the following output:
Error: Undefined symbol 'X'
Can someone please explain the output?
It is because the macro expects and argument since its defined with parentheses.
You would need to define it as
#define X 4+Y and #define Y X+3. Then you would run into another trouble because of cyclic definition in macros.
To be even more correct, as Drew suggested; when the example would be compilable when defining macros one usually puts the parentheses around expression to ensure expected operator precedence.
So your best shot would be:
#define X (4+Y)
#define Y (X+3)
Very close to your initial example, just a space character between name of a macro and its definition. However, it is still impossible to properly expand the macro due to the cyclic reference.
How to check what happened:
You can use gcc -E, which outputs a pre-processed file. It generates lots of output so I used tail. I also used 2>err to redirect error stream to a file, so the output is clear.
luk32:~/projects/tests$ gcc -E ./cyclic_macro_with_no_spaces.c 2> err | tail -n 6
int main()
{
printf("%d",4*X+2);
return 0;
}
luk32:~/projects/tests$ gcc -E ./cyclic_macro.c 2> err | tail -n 6
int main()
{
printf("%d",4*(4+(X+3))+2);
return 0;
}
In 1st example the X did not expand at all. While in the latter both macros got expanded, although only one. Giving the same output that Geoffrey presented in his answer.
Whether no space is a typo or not there is an undefined symbol 'X'. For different reason that are possible to trace by analyzing err files.
If the macros are left as invalid function-like macros, they are not getting expanded at all because you did not call it with parentheses. So X is never replaced with anything by the pre-processor, and is the reason for the Undefined symbol 'X' in your sample code.
If you wanted this to be expanded you would have to call it with parentheses like this:
printf("%d",4*X()+2);
This though would just error out when pre-processed as 4+Y and X+3 are not valid macro parameter names.
If your answer is corrected somewhat so that those defines are proper defines, and not function-like macros, ie:
#define X (4+Y)
#define Y (X+3)
You have a circular reference between the defines...
X -> Y -> X... etc.
Since it will only expand the macro once, it is getting expanded to
printf("%d",4*(4+(X+3))+2);
This explains why X is the undefined symbol in this use case.
You miss spaces
#define X (4+Y)
#define Y (X+3)

Resources