macro with arguments - c

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 . */

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

Renaming a macro in C

Let's say I have already defined 9 macros from
ABC_1 to ABC_9
If there is another macro XYZ(num) whose objective is to call one of the ABC_{i} based on the value of num, what is a good way to do this? i.e. XYZ(num) should call/return ABC_num.
This is what the concatenation operator ## is for:
#define XYZ(num) ABC_ ## num
Arguments to macros that use concatenation (and are used with the operator) are evaluated differently, however (they aren't evaluated before being used with ##, to allow name-pasting, only in the rescan pass), so if the number is stored in a second macro (or the result of any kind of expansion, rather than a plain literal) you'll need another layer of evaluation:
#define XYZ(num) XYZ_(num)
#define XYZ_(num) ABC_ ## num
In the comments you say that num should be a variable, not a constant. The preprocessor builds compile-time expressions, not dynamic ones, so a macro isn't really going to be very useful here.
If you really wanted XYZ to have a macro definition, you could use something like this:
#define XYZ(num) ((int[]){ \
0, ABC_1, ABC_2, ABC_3, ABC_4, ABC_5, ABC_6, ABC_7, ABC_8, ABC_9 \
}[num])
Assuming ABC_{i} are defined as int values (at any rate they must all be the same type - this applies to any method of dynamically selecting one of them), this selects one with a dynamic num by building a temporary array and selecting from it.
This has no obvious advantages over a completely non-macro solution, though. (Even if you wanted to use macro metaprogramming to generate the list of names, you could still do that in a function or array definition.)
Yes, that's possible, using concatenation. For example:
#define FOO(x, y) BAR ##x(y)
#define BAR1(y) "hello " #y
#define BAR2(y) int y()
#define BAR3(y) return y
FOO(2, main)
{
puts(FOO(1, world));
FOO(3, 0);
}
This becomes:
int main()
{
puts("hello " "world");
return 0;
}

Macro expansion of __typeof__ to function name

I wrote the following code in plain C:
#define _cat(A, B) A ## _ ## B
#define cat(A, B) _cat(A, B)
#define plus(A, B) cat(cat(plus,__typeof__(A)),__typeof__(B))(A, B)
int main(int argc, const char * argv[])
{
double x = 1, y = 0.5;
double r = plus(x, y);
printf("%lf",r);
return 0;
}
Here, I would like the macro plus to be expanded becoming a function name which contains the types of the parameters. In this example I would like it to expand the following way
double r = plus(x, y)
...
/* First becomes*/
double r = cat(cat(plus,double),double)(x, y)
...
/* Then */
double r = cat(plus_double,double)(x, y)
...
/* And finally */
double r = plus_double_double(x, y)
However all I got from the preprocessor is
double r = plus___typeof__(x)___typeof(y)(x,y)
and gcc will obviously refuse to compile.
Now, I know that typeof evaluates at compile-time and it is my understanding that a macro is only prevented from being evaluated when it is contained in second macro which directly involves the stringify #and the concatenation ## tokens (here's the reason why I split cat in the way you see). If this is right, why doesn't __typeof__(x) get evaluated to double by the preprocessor? Seems to me that the behaviour should be perfectly clear at build time. Shouldn't __typeof__(x) evaluate to double before even going in _cat?
I searched and searched but I couldn't find anything... Am I doing something really really stupid?
I'm running Mac OS X Mountain Lion but I'm mostly interested in getting it work on any POSIX platform.
The reason this does not work is typeof is not a macro but a reserved word in the gcc's dialect of C and is thus handled after the preprocessor has finished its work. A good analogy would be the sizeof operator which is not a macro either and is not expanded by the preprocessor. To do (approximately) what you want (pick a different function based on the type of the arguments) try the _Generic construct (new in C11)
Macro expansion occurs before C token analysis (see https://stackoverflow.com/a/1479972/1583175 for a diagram of the phases of translation)
The macro preprocessor is unaware of the type information -- it merely does text processing
The preprocessor knows nothing about types, only about textual tokens. __typeof__() gets evaluated by the compiler pass, after the preprocessor has finished performing macro replacements.

macro arguments

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++

Resources