MACROs internal working - c

#include<stdio.h>
#define MUL( a, b) a##b
int main( )
{
//static int a = 5;
// while( --a )
printf("%d",MUL(2+3,4+5));
//{
// printf("%d ",a);
// main(10);
//}
return 0;
}
OUTPUT: 41
why the output of the program is 41?
I am using token pasting operator that should merge the two numbers.
I am expecting the output as 59 but its showing 41.

When a macro is expanded, the two tokens on either side of each ‘##’ operator are combined into a single token. Expressions are not evaluated and passed to the macro.
In this case the expansion would be 2+3 ## 4+5 i.e 2 + 34 + 5 = 41.

After replacement it will look like
printf("%d", 2+34+5) ); // 2+34+5 = 41
It will never print 28.
The argument to MUL will not evaluate before the replacement.

MUL(2+3,4+5)
will expand to
2+3##4+5
which is
2+34+5
It evaluates to 41.
To get 59, you need to call MUL(5,9). For even MUL((2+3),(4+5)), preprocessing will be done first which will make it to
(2+3)(4+5)
and will result in compiler error.
MACROs are replaced before compilation phase.

Related

Unable to understand the output of program in C

EDIT: This question is not duplicate as the behavior is not undefined in this case.
Why does the below program print the output as 231 in first line?
I have two doubts regarding this:
As I am doing postfix increment the value of x shouldn't have been increased before the I call max function. So the output should have been 1 in the first place instead of 2 according to me. What am I missing?
#define prn(a) printf("%d",a)
#define print(a,b,c) prn(a), prn(b), prn(c)
#define max(a,b) (a<b)? b:a
main()
{
int x=1, y=1;
print(max(x++,y),x,y);
printf("\n");
print(max(x++,y),x,y);
}
Output:
231
451
The postfix operation occurs after execution of the statement? Consider the example below.
int main()
{
int x = 0, y = 1;
int a = x++ /*x is incremented hereafter?*/+ y; // line 1
/* Or x is incremented now after execution of above line?*/ // line 2
int b = 0;
}
let me take this line
print(max(x++,y),x,y);
One important point to note is that the C preprocessor is a macro preprocessor (allows you to define macros) that transforms your program before it is compiled. These transformations can be inclusion of header file, macro expansions etc.
All preprocessing directives begins with a # symbol. For example,
#define PI 3.14
tells the compiler to replace the value PI with 3.14 where ever it sees.
c source code->preprocessor->compiler
therefore print(max(x++,y),x,y) is expanded in macro to
1. prn((x++<y) ? y:x++), prn(x), prn(y)
2. printf("%d",(x++<y)? y:x++), printf("%d",x), printf("%d",y);.
here it gets processed you can check two things carefully here
while checking
x++<y ,the x++ value is 1
then after that the x value becomes 2
so 2 is printed
and then while printing also we wrote x++ that means here x++ VALUE IS 2 but
after that x value is 3
so 3 is printed and it follows y as 1
that 's how it works
2.TO give you a great intuition on preincrement and post increment
let me take an example
int x=2;//value of x is 2
x++;//here x++ value is 2
after this line execution x value changed to 3
++x//here x++ value is 4 and also x value is 4.

Passing macro arguments to macro function

How do I pass macro arguments along with another integer variable to a macro function?
#define SUM(X, Y, Z) X + Y + Z
#define FOO 1, 2
void print(int a, int b)
{
printf("Sum: %d", a + b);
}
int main(void)
{
// Normal function works as expected
print(FOO);
// Macro function not working
int a = 3;
printf("\nMacro Sum: %d", SUM(FOO, a));
return 0;
}
I expect the output to be:
Sum: 3
Macro Sum: 6
However, I get the following error:
main.c:18:41: error: macro "SUM" requires 3 arguments, but only 2 given
printf("\nMacro Sum: %d", SUM(FOO, a));
Macro arguments are not expanded when the macro call is parsed. After the macro call is parsed, each use of a macro parameter in the macro definition text is replaced with the macro-expanded argument, except for macro parameters used with the # or ## operations (stringify and token paste), which are replaced with the unexpanded text of the macro argument. Then the # and ## operations are performed, and then the entire macro body is scanned one more time.
The consequence is that SUM(FOO, a) is parsed aa having two arguments. Since the macro requires three, thatvwon't compile.
You can work around this, to some extent, by using one extra level of macro expansion:
#define CALL(macro, ...) macro(__VA_ARGS__)
printf("\nMacro Sum: %d", CALL(SUM, FOO, a));
Now the use of the __VA_ARGS__ parameter (which happens to be a varargs parameter, although that makes absolutely no difference to the expansion order) will be expanded before the replacement text is rescanned, so FOO will be invoked with three arguments.
By the way, outputting a newline character at the beginning of an output line is a bad habit which will get you into trouble someday. Output lines should have a newline at the end of the line:
printf("Macro Sum: %d\n", CALL(SUM, FOO, a));
There is nothing wrong with also writing a blank line beforehand by putting a newline at the beginning as well, but regardless, you should almost always terminate outpur lines with the \n. Otherwise:
The line might not be written immediately. Line-buffered output is not actually sent to the output device/file until a newline is sent.
If the program is a console app and it terminates without properly closing stdout, you will find yourself typing the next shell command at rhe end if the last output line. This tends to confuse line-editing input libraries like readline.
Single macro argument would work:
#define SUM(X, Y, Z) X + Y + Z
#define FOO1 (1)
#define FOO2 (2)
void print(int a, int b)
{
printf("Sum: %d", a + b);
}
int main(void)
{
// Normal function works as expected
print(FOO1,FOO2);
int a = 3;
printf("\nMacro Sum: %d", SUM(FOO1, FOO2, a));
return 0;
}
Output:
Sum: 3
Macro Sum: 6

use of ## and # operator to concatenate the strings in a macro in C

I am having a code which requires to concatenate strings as shown below:
#define CMD(A,B) CMD_##A_PROMPT##B
void main()
{
int a = 10, b = 5;
printf("%s\n", CMD(a, b));
}
the desired output is: CMD10_PROMPT5
Can this be achieved by any means?
I don't think that this can be done, because the macro you're looking for is a compile-time "stringification", an the parameters receive their values at run-time.
If you're looking for run-time "stringification", use sprintf and the like.
You can do it by replacing int a = 10, b = 5; with:
#define a 10
#define b 5
Otherwise it's not possible. C translation occurs in a series of phases defined in the standard, and preprocessing phase occurs before any object definitions are parsed. As far as the preprocessor is concerned, int a = 10 does not establish any relationship between the token a and the token 10.
If all you're after is the output, do it like this:
#define CMD_PATTERN "CMD_%d_PROMPT%d"
int main() {
int a = 10, b = 5;
printf(CMD_PATTERN "\n", a, b);
}
There's unfortunate requirement that the arguments are supplied in the same order that they appear in the pattern - this makes it difficult to change the order in future. For that reason, it might be better to define a formatting function rather than just a pattern.

Lvalue required error with macro

Why does the following code report an Lvalue required error?? And how can we write a macro that receives an array and the number of elements in the array as arguments and then print out the elements of the array??
#define arr(b) printf("%d",b++);\
printf("%d",b);
int main()
{
arr(5);
}
If you expand the macro, you get the following:
int main()
{
printf("%d",5++);
printf("%d",5);
}
You cannot postincrement the constant 5, so you get an error.
Remember, macros aren't functions. If you want it to act like a function, simply make a function:
void arr(int b) {
printf("%d",b++);
printf("%d",b);
}
Because part of that macro expands to 5++, which is not valid C. Consider using b+1 instead of b++.
The first l in lvalue stands for left.
Only left values can be assigned.
when you write x ++ you mean x = x + 1 (also you get a value from it).
So the problem is it does not make sense to write 5 = 5 + 1
maybe you would like to do this:
int x = 5;
arr(x);

C #define macros

Here is what i have and I wonder how this works and what it actually does.
#define NUM 5
#define FTIMES(x)(x*5)
int main(void) {
int j = 1;
printf("%d %d\n", FTIMES(j+5), FTIMES((j+5)));
}
It produces two integers: 26 and 30.
How does it do that?
The reason this happens is because your macro expands the print to:
printf("%d %d\n", j+5*5, (j+5)*5);
Meaning:
1+5*5 and (1+5)*5
Since it hasn't been mentioned yet, the way to fix this problem is to do the following:
#define FTIMES(x) ((x)*5)
The parentheses around x in the macro expansion prevent the operator associativity problem.
define is just a string substitution.
The answer to your question after that is order of operations:
FTIMES(j+5) = 1+5*5 = 26
FTIMES((j+5)) = (1+5)*5 = 30
The compiler pre-process simply does a substitution of FTIMES wherever it sees it, and then compiles the code. So in reality, the code that the compiler sees is this:
#define NUM 5
#define FTIMES(x)(x*5)
int main(void)
{
int j = 1;
printf("%d %d\n", j+5*5,(j+5)*5);
}
Then, taking operator preference into account, you can see why you get 26 and 30.
And if you want to fix it:
#define FTIMES(x) ((x) * 5)
the preprocessor substitutes all NUM ocurrences in the code with 5, and all the FTIMES(x) with x * 5. The compiler then compiles the code.
Its just text substitution.
Order of operations.
FTIMES(j+5) where j=1 evaluates to:
1+5*5
Which is:
25+1
=26
By making FTIMES((j+5)) you've changed it to:
(1+5)*5
6*5
30

Resources