macro arguments - c

What will the program print when the inputs are 2,3?
#include <stdio.h>
#define min(a,b) ((a) > (b) ? (b) : (a))
#define inc(a) a++
#define mult(a,b) (a * b)
int main(void) {
int x = 1, y = 2;
scanf("%d %d",&x,&y);
printf("min(%d,inc(%d))",x,y);
printf("=%d\n",min(x,inc(y)));
printf("min(mult(%d,%d+2),11)",x,y);
printf("=%d\n",min(mult(x,y+2),11));
return 0;
}
edit: I get funny answer for negative numbers i.e -1,-2.
Why is inc(-2) change y to zero instead of -1?

Think of a macro as simply string replacement. Just replace the macro name and parentheses with the body of the macro definition, replacing the macro parameters with what is passed in. An example is easier:
#define hello(a) a+a
...
int y = hello(x);
Would be replaced with:
int y = x+x;
To answer your question, do this manually, and very, very carefully. For nested macros, start with the inside one. Did I mention do this carefully? Don't add or remove any sets of parentheses.

The output would be:
min(2,inc(3))=2
min(mult(2,4+2),11)=11
What do you mean with overwrite?
If you define a function like you did above and call for example this:
inc(x);
.. then the compiler turns it into x++. The variable a is just a name for the "paramter" and will also be replaced by the real variable.

What operating system are you running? you can easily run this yourself and see the results
if your on Windows I would suggest getting CodeBlocks or Visual Studios
if your on Linux or MAC , learn to compile from terminal using gcc or g++

Related

Why is the output different in these two scenarios

Please give me full description....
The first snippet of code has the 'function call' (macro invocation) before the increment operator, and second one has the function call after the increment operator.
#include <stdio.h>
#define square(x) x*x
int main()
{
int a,b=3;
a=square (b)++;
printf("%d%d",a,b);
return 0;
}
output:
124
why is 124 returned here
#include <stdio.h>
#define square(x) x*x
int main()
{
int a,b=3;
a=square (b++);
printf("%d%d",a,b);
return 0;
}
output:
125
and 125 here?
The thing to keep in mind is that macros provide simple substitution of preprocessor tokens. In particular, they may evaluate their arguments more than once, and if not guarded by parentheses, they may produce unintended reassociation.
In the first example, we have
a=square (b)++;
This expands to:
a=b*b++;
This is actually undefined behavior, since the b and b++ are unsequenced, and b++ modifies b. In your case, you are seeing 12 and 4 for a and b, so it would seem that the first value of b is picking up the incremented value, so you're getting 4*3, but you can't count on this behavior. The final value of b is 4 since it is incremented once.
In the second example, we have:
a=square (b++);
This expands to:
a=b++*b++;
This is again undefined behavior. In your case, it appears that you're getting 4*3 (or 3*4), but again, you can't count on this behavior. The final value of b is 5 since it is incremented twice, but this too is undefined behavior.
In addition to Tom's answer, which explains what is happening, here is an example of how you could define a macro for squaring a number safely:
#define SQR(x) ( \
{ \
__auto_type x_ = (x); \
\
x_ * x_; \
} \
)
It only has an appearance of x, and therefore it doesn't evaluate it twice. The copy x_ is used instead. Note that variables created in a macro may conflict with other variables created in the function that calls the macro. To avoid name collisions you use special names that shouldn't be used in normal code such as a trailing _.
With this macro, this:
a = SQR(b++);
will be equivalent to this:
a = SQR(b);
b++;
Warning: This works on some compilers as an extension (GCC for example), but it is not standard C.
Another option, if you want standard C, is to use an inline function. It is ok if you want it to work on just one type (there is _Generic in C11, but I never used it, so no idea).

Difference between macros and Functions in C language

I'm new to C language. When I'm learning C language I learn something called macros. As I understood macros are like a functions in JavaScript that we can call when we needed. But then I learn that after compiling the program all the places that i have called to macros are replaced by the definition of the macro. So I'm confusing what is the difference between macro and a function in C language.
Also I wanna know whether I can write multi line macros in my code and if it is possible how it will be replaced when the code compiled.
As a example assume that I wanna macro to find the maximum value among two numbers.
Is it a good practice to write that process as a macro rather than write is as a function.
Everything stands - don't use macro. A better alternative inline the function - it would achieve the same efficiency you expect. But for fun, I worked a bit to use gcc statement expressions that means a non-portable gcc centric solution.
#include <stdio.h>
#define SUM(X) \
({ long s = 0; \
long x = (X) > 0 ? (X) : (-(X)); \
while(x) { \
s += x % 10; \
x /= 10; \
} \
s; \
})
int main(void) {
printf("%ld\n",SUM(13423) );
return 0;
}
This solution begs for a function. Using statement expression to have that return something feature inside macro. Well I said, go for inline function. That would serve the purpose much cleaner way.
Using macros is sometimes dangourous:
https://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html#Macro-Pitfalls
you can read on the dangers of using it here..
but, for your question:
#include <stdio.h>
#define SUM(X, Y) (X + Y)
void main() {
printf("the sum of 3,4 is : %d\n", SUM(3,4));
}
will output:
the sum of 3,4 is : 7

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)

macro with arguments

Let's say I define macro with arguments, then invoke it as follows:
#define MIN(x,y) ((x)<(y)?(x):(y))
int x=1,y=2,z;
z=MIN(y,x);
Given that (a) macro works as text substitution, (b) that actual args here are like formal args, only swapped, -- will this specfic z=MIN(y,x) work as expected ? If it will, why ?
I mean, how preprocessor manages not to confuse actual and formal args ?
This question is about technicalities of C compiler. This is not c++ question.
This question does not recommend anybody to use macros.
This question is not about programming style.
The internal representation of the macro will be something like this, where spaces indicate token boundaries, and #1 and #2 are magic internal-use-only tokens indicating where parameters are to be substituted:
MIN( #1 , #2 ) --> ( ( #1 ) < ( #2 ) ? ( #1 ) : ( #2 ) )
-- that is to say, the preprocessor doesn't make use of the names of macro parameters internally (except to implement the rules about redefinitions). So it doesn't matter that the formal parameter names are the same as the actual arguments.
What can cause problems is when the macro body makes use of an identifier that isn't a formal parameter name, but that identifier also appears in the expansion of a formal parameter. For instance, if you rewrote your MIN macro using the GNU extensions that let you avoid evaluating arguments twice...
#define MIN(x, y) ({ \
__typeof__(x) a = (x); \
__typeof__(y) b = (y); \
a < b ? a : b; \
})
and then you tried to use it like this:
int minint(int b, int a) { return MIN(b, a); }
the macro expansion would look like this:
int minint(int b, int a)
{
return ({
__typeof__(b) a = (b);
__typeof__(a) b = (a);
a < b ? a : b;
});
}
and the function would always return its first argument, whether or not it was smaller. C has no way to avoid this problem in the general case, but a convention that many people use is to always put an underscore at the end of the name of each local variable defined inside a macro, and never put underscores at the ends of any other identifiers. (Contrast the behavior of Scheme's hygienic macros, which are guaranteed to not have this problem. Common Lisp makes you worry about it yourself, but at least there you have gensym to help out.)
It will work as expected.
#define MIN(x, y) ((x) < (y) ? (x) : (y))
int x=1,y=2,z;
z = MIN(y, x);
becomes
int x=1,y=2,z;
z = ((y) < (x) ? (y) : (x));
Does the above have any syntactic or semantic errors? No. Therefore, the result will be as expected.
Since you're missing a close ')', I don't think it will work.
Edit:
Now that's fixed, it should work just fine. It won't be confused by x and y any more than it would be if you has a string x with "x" in it.
First off, this isn't about the C compiler, this is about the C Pre-processor. A macro works much like a function, just though text substitution. What variable names you use make no impact on the outcome of the macro substitution. You could have done:
#define MIN(x,y) ((x)<(y)?(x):(y))
int blarg=1,bloort=2,z;
z=MIN(bloort,blarg);
and get the same result.
As a side node, the min() macro is a perfect example of what can go wrong when using macros, as an exercise you should see what happens when you run the following code:
int x,y,z;
x=1;y=3;
z = min(++x,y);
printf("%d %d %d\n", x,y,z); /* we would expect to get 2 3 2, but we get 3 3 3 . */

C program output is confusing

#include<stdio.h>
#include<conio.h>
#define PROD(x) (x*x)
void main()
{
clrscr();
int p=3,k;
k=PROD(p+1); //here i think value 3+1=4 would be passed to macro
printf("\n%d",k);
getch();
}
In my opinion, the output should be 16, but I get 7.
Can anyone please tell me why?
Macros are expanded, they don't have values passed to them. Have look what your macro expands to in the statement that assigns to k.
k=(p+1*p+1);
Prefer functions to macros, if you have to use a macro the minimum you should do is to fully parenthesise the parameters. Note that even this has potential surprises if users use it with expressions that have side effects.
#define PROD(x) ((x)*(x))
The preprocessor expands PROD(p+1) as follows:
k = (p+1*p+1);
With p=3, this gives: 3+1*3+1 = 7.
You should have written your #define as follows:
#define PROD(x) ((x)*(x))
The problem here is that PROD is a macro and will not behave exactly like you intend it to. Hence, it will look like this:
k = p+1*p+1
Which of course means you have:
k = 3+1*3+1 = 7
#define PROD(x) (x*x)
PROD(3+1) is changed by the preprocessor to 3+1*3+1
macro are not function . These are replaced by name
It will be p+1*p+1
This is what compiler is going to see after preprocessors does its job: k= p+1*p+1. When p = 3, this is evaluated as k = 3+(1*3)+1. Hence 7.
This is exactly why you should use functions instead of macros. A function only evaluates each parameter once. Why not try
int prod(int x)
{ return x * x; }
and see the difference!

Resources