#define statement with multiple elements separated by commas - c

I'm looking at something like this:
#define foo(x) \
(((a > b) ? \
0 : 1), \
(c ? 2 : 3), \
(d ? 4 : 5))
I'm not sure how to interpret this. Can someone help me out?

Essentially the \ ignores the newline as far as terminating the #define statement is concerned, so each time you write foo(var) in your code it will be replaced with
((((a > b) ?
0 : 1),
(c ? 2 : 3),
(d ? 4 : 5))
The comma operator doesn't do a whole lot, except the final "returned" value of a statement consisting of statements separated by comma operators is the right most value.
All of that being explained, this isn't really a terribly valid #define since you use a,b,c, and d in the #define and only reference x as a parameter

The comma operator evaluates all of its operands and returns the value of the last one. So, a, b, c and d will be evaluated and the result of f(x) will be either 4 or 5, depending on whether d is non-zero.

Related

I can not understand Macro function`s result in C language

--
Hello,
I can`t understand why "#define max(a,b) (a>b)?(a):(b)" does not work that i expected.
#include<cstdio>
#define max(a,b) (a>b)?(a):(b)
int main(void){
printf("%d\n",max(3,5)); // result = 5 (work correctly)
int a = 3 + max(3,5);
printf("%d\n",a); // result = 3 (work incorrect and i don`t know why..)
}
i can`t why variable + macro does not work.
but, In this case "#define max(a,b) ((a>b)?(a):(b))" work correctly. even that var + macro situation.
plz anybody clarify this.. thx.
When you have this:
#define max(a,b) (a>b)?(a):(b)
And you write this:
int a = 3 + max(3,5);
That expands to:
int a = 3 + (a>b)?(3):(5)
Because + has a higher operator precendence than ?, this is effectively:
int a = (3 + (a>b)) ? (3) : (5)
And since 3 + (a>b) is always going to evaluate to a true-ish value, the result will always be 3.
By putting the whole expansion in parentheses:
#define max(a,b) ((a>b)?(a):(b))
You get instead:
int a = 3 + ((a>b)?(3):(5))
Because the outer parentheses group the ternary operator expression, you get the result you expect.
Note that as #zwol writes in a comment, you should actually write your macro like:
#define max(a,b) (((a)>(b))?(a):(b))
The extra parentheses around a and b in (a)>(b) protect against exactly this sort of operator precedence problem.
Operator precedence. I get a warning with clang.
test.cc:7:15: warning: operator '?:' has lower precedence than '+'; '+' will be evaluated first [-Wparentheses]
int a = 3 + max(3,5);
Easy to fix with parenthesis.
#define max(a,b) ((a>b)?(a):(b))

Does macro function with operator precedence show unusual result?

#define SQUARE(x,y) (x<y?x:y)
int a = 5, b = 6, c = 3;
int var = SQUARE(a & c,b);
I have searched and learnt that '<' precede '&'. As per rules it should give '5'. But it is giving output as '1'. But in some cases it is giving right output. Can you please explain macro rules of this and what am I missing here.
Macros are just replaced by the preprocessor, so the arguments are not evaluated and then passed like in functions.
In your example the expression SQUARE(a & c, b); will become (a & c < b ? a & c : b);
For a=5, b=6, c=3 it evaluates to:
(5 & 3<6 ? 5&3 : 6) //'<' precede '&' as you correctly mentioned
(5&1 ? 5&3 : 6) // '3 < 6' is a boolean expression which evaluates to 1. '&' is bitwise AND.
(1 ? 1 : 6)
(1)
So 1 is the right output.
EDIT:
A good aproach is to always use parentheses around your arguments and the whole expression to eliminate the problem of operator precedence.
As mention by others it can be dangerous to use macros due to multiple evaluation, which may not only effect performance.
For example:
#define SQUARE(x) ((x)*(x))
seems to only square the argument, but if you call it like
f = SQUARE(x++);
you will get undefined behaviour. A better approach for small function would be to declare it as inline.
inline int square(int x)
{
return x*x;
}
Also as mentioned by #EricPostpischil macros are not a textual replacement as the preprocessor replaces by tokens.
For example:
#define a 1
#define b 2
printf("%d\n", ab);
here ab is not replaced with 12 as someone would expect for pure textual replacement.
Macros require parentheses as they are not functions and just do the textual replacement
#define SQUARE(x,y) (((x)<(y))?(x):(y))
The macro is extremely side effects error and UB prone:
Example: SQUATE(x++,y)
in your example 5 & 3 will be evaluated every time you have the x in your macro. It will be less effective than the inline function
inline unsigned SQUARE(unsigned x, unsigned y)
{
return (x < y) ? x : y;
}
In a bit more detail, as #P__J__ said, macros are just text replacement by the pre-processor, not functions. So this:
#define SQUARE(x,y) (x<y?x:y)
int a = 5, b = 6, c = 3;
int var = SQUARE(a & c,b);
is translated to:
int a = 5, b = 6, c = 3;
int var = (a & c<b?a & c:b);
Because every x is replaced with a & c and every y is replaced with b.
If you also apply the values as in #Osiris 's answer, you'll get:
int var = (5 & 3 < 6 ? 5 & 3 : 6);
At this point, as you already said, < takes precedence over &.
The result of < is true or false, which means 1 or 0, so 3 < 6 becomes 1.
The result of & is the bitwise AND between two numbers, which in this case is also 1 (because 5 is 101 and 3 is 011).
This is why it becomes
(5 & 1 ? 1 : 6)
That next 5 & 1 will also become 1 (because of the AND between 101 and 001), so you'll get:
(1 ? 1 : 6)
And since 1 is true, you'll get the first value, which is also a 1.
Also, as already pointed out, be careful with evaluation in a macro.
These are just numbers and you're already seeing some not so obvious behaviour, but if had passed a function as one of the arguments, that function would've run multiple times.
For example
#define SQUARE(x,y) (x<y?x:y)
int var = SQUARE(update_counter(a), 1);
would have been translated to
int var = (update_counter(a) < 1 ? update_counter(a) : 1);
Thus potentially updating a hypothetical counter twice.

what is the difference of these two macro max?

writing leetcode
I use the macro like this:
#define max(a,b) ((a) > (b))?(a):(b)
it is wrong,when i change the macro like this,it's right
#define max(a,b) (((a) > (b))?(a):(b))
can't figure out why does this different.Here is the code,you can check it out.
#define UNBALANCED 99
#define max(a,b) (((a) > (b))?(a):(b))
int getHeight(struct TreeNode * root)
{
if(NULL == root)
return -1;
int l = getHeight(root->left);
int r = getHeight(root->right);
if(UNBALANCED == l || UNBALANCED == r || abs(l-r) > 1)
return UNBALANCED;
return 1 + max(l,r);
}
bool isBalanced(struct TreeNode* root)
{
if(NULL == root)
return true;
return getHeight(root) != UNBALANCED;
}
that is different with The need for parentheses in macros in C
The former fails to isolate the macro replacement from neighboring operands. For example:
1 + max(a, b)
expands to:
1 + ((a) > (b))?(a):(b)
and that groups as:
(1 + ((a) > (b))) ? (a) : (b)
Then (1 + ((a) > (b))) is always nonzero, so (a) is always chosen.
To prevent this, a macro that expands to an expression should use parenthesis around its entire expression to prevent its parts from grouping with neighboring operands.
The second version of your macro has extra parentheses which make the expression ((a) > (b))?(a):(b) evaluated as a whole. More code would be needed to explain exactly why the first one is wrong in your case. Also, see this.
Arguably both of them are incorrect; what if you wanted to use your macro like:
MAX(i++, j++)
The resulting ternary-operator expression from your examples cause whichever expression is smaller to be evaluated twice. Yowch! Since you (and most future readers) likely use GCC or clang, here's a better example with some compiler extensions (__typeof__ and statement expressions) that both of them support.
#define MAX(a, b) ({ __typeof__ (a) a__ = (a); \
__typeof__ (b) b__ = (b); \
(a__ > b__) ? a__ : b__; })

operator ++ applied two times, depending on arguments to #define function [duplicate]

This question already has answers here:
Problem with Macros
(4 answers)
Closed 9 years ago.
On the snipet below, the operator ++ is called two times.
Why ??
#define CALL_WITH_MAX(a,b) ((a) > (b) ? (a) : (b))
int main()
{
int a = 5, b =0;
CALL_WITH_MAX(++a,b);
// a was incremented by one two times !!!!
CALL_WITH_MAX(++a,b+10);
//a incremented as expected...
return 0;
}
CALL_WITH_MAX(++a,b)
expands to
((++a) > (b) ? (++a) : (b))
^ ^ //A is incremented twice when ++a < b
++a = 6 and b = 0
6 > 0 == true
++a is returned => ++a = 7
In your second option
++a = 6 and b = 0 + 10 = 10
6 > 10 == false.
This time just b is returned.
Because argument is taken as is - without extracting variable names, etc. That's what it becomes:
((++a) > (b) ? (++a) : (b));
As incremented a is greater than b, the second part of ternary expression will be evaluated as well.
In the second case, however, the clause is falsy: 6 is less than 10. That's why third part of the ternary is evaluated instead, and a will be incremented just once.
If the first argument is larger than the second, it is evaluated 2 times.
Therefore in the first case you have:
(++a) > (b) ? (++a) : (b)
and since (++a) > (b) you get (++a), which increments a once more.
If you expand the macro it will become like
((++a) > (b) ? (++a) : (b))
6 > 0 then a is again incremented.
The macro expands to:
((++a) > (b) ? (++a) : (b))
vs.
((++a) > (b+10) ? (++a) : (b+10))
in the former, ++a is evaluated twice
The macro is not "compiled", it's completely different from writing a function you run during the execution of your application. Treat a macro as something that helps you write your code, not perform calculations.
Therefore
CALL_WITH_MAX(++a,b)
will generate
((++a) > (b) ? (++a) : (b));
which then is "read" by the compiler and compiled to actual code. This means that a will be incremented twice, because b is smaller than a, and therefore the (++a) is run. If b is larger, then the second (++a) is not executed and only b is returned.
This is why macros are also known as preprocessor directives, because they are used in the preprocessing phase of the build process. The values of the variables are not read or changed, the directive just reads the text you provide it with and generates code for you.
If you look at macros that already exist like __LINE__, it will return the line number for you in your code; however it will literally insert it as part of your code, it will not be a function that is run during the execution of your application. Similarly the macro __TIME__ will not return the current time but the time of when the compilation process was started.
I hope this will help you to change your approach to macros and how they work.
Most of the answers on this questions are correct. Here is a typical fix for the issue:
#define CALL_WITH_MAX(a,b) ({ typeof(a) _a=a; typeof(b) _b=b; ((_a) > (_b) ? (_a) : (_b)); })
Works with gcc.
Basically, it creates a copy of a & b, with same data types & operates on these copies.
The only time a gets incremented is at _a=a; statement in macro.
You can test the expansion with -E flag to gcc; like gcc -E test_macro.c ...
The prefixed increment operator has higher order of procedure so the value of the variable is increased by 1 before evaluation .
you call your function with arguments (++a,b) so you need to replace all the variable with this passed value so the function can be expressed as
`CALL_WITH_MAX(a,b) ((a) > (b) ? (a) : (b))
CALL_WITH_MAX(++a,b); `
so if you replace all a by ++a and b and b then your function can be expressed as
((++a) > (b) ? (++a) : (b))
the value of a is incremented by 1 before evaluation ..
I noticed in your code, you chose to name the macro's parameters a and b, which is also the name you used for your variables within your main function.
In my opinion, the problem you're having here is you probably think by naming them the same that they're linked somehow.. which is simply not true.
The parameters names in the macro don't tie them to variables of the same name in the program, they’re replaced by what you pass in. You might find this easier to see if we change the names a bit:
#define CALL_WITH_MAX(x,y) ((x) > (y) ? (x) : (y))
Then in your main program:
int a = 5, b =0;
CALL_WITH_MAX(++a,b);
Now you can see that x is replaced with ++a and y will be replaced by b. So the logic of your macro becomes:
if x > y then return x else return y
if ++a > b then return ++a else return b
if 6 > 0 then return 7 else return 0
So obviously 6 is greater than 0, so you increment again and return the value.
// a = 7; b = 0
CALL_WITH_MAX(++a,b+10);
So again, the same logic:
if x > y then return x else return y
if ++a > b then return ++a else return b
if 8 > 10 then return 9 else return 10
In this case 8 is not greater than 10, so we don't increment to 9, we just return 10. Thus after the first call to your macro a was incremented twice and after the second call a was only incremented once; hope that made it clearer.

C Macro for minimum of two numbers

I want to make a simple macro with #define for returning the smaller of two numbers.
How can i do this in C ? Suggest some ideas, and see if you can make it more obfuscated too.
Typically:
#define min(a, b) (((a) < (b)) ? (a) : (b))
Be warned this evaluates the minimum twice, which was the reason for disaster in a recent question.
But why would you want to obfuscate it?
This one stores the result in a variable, and only evaluates each argument once. It's basically a poor-mans inline function + declaration:
#define min(t, x, a, b) \
t x; \
{ \
t _this_is_a_unique_name_dont_use_it_plz_0_ = a; \
t _this_is_a_unique_name_dont_use_it_plz_1_ = b; \
x = _this_is_a_unique_name_dont_use_it_plz_0_ < \
_this_is_a_unique_name_dont_use_it_plz_1_ ? \
_this_is_a_unique_name_dont_use_it_plz_0_ : \
_this_is_a_unique_name_dont_use_it_plz_1_ ; \
}
Use it like:
min(int, x, 3, 4)
/* x is an int, equal to 3
Just like doing:
int x = min(3, 4);
Without double evaluation.
*/
And, just for the hell of it, a GNU C example:
#define MAX(a,b) ({ \
typeof(a) _a_temp_; \
typeof(b) _b_temp_; \
_a_temp_ = (a); \
_b_temp_ = (b); \
_a_temp_ = _a_temp_ < _b_temp_ ? _b_temp_ : _a_temp_; \
})
It's not obfuscated, but I think this works for any type, in any context, on (almost, see comments) any arguments, etc; please correct if you can think of any counterexamples.
Sure, you can use a #define for this, but why would you want to? The problem with using #define, even with parentheses, is that you get unexpected results with code like this (okay, you wouldn't actually do this, but it illustrates the problem).
int result = min(a++, b++);
If you're using C++ not C, surely better to use an inline function, which (i) avoids evaluating the parameters more than once, and (ii) is type safe (you can even provide versions taking other types of value, like unsigned, double or string).
inline int min(int a, int b) { return (a < b) ? a : b; }
I think this method is rather cute:
#define min(a, b) (((a) + (b) - fabs((a) - (b))) * 0.5)
I want to make a simple macro with #define for returning the smaller of two numbers.
I wanted to add a solution when the numbers are floating point.
Consider when the numbers are floating point numbers and one of the numbers is not-a-number. Then the result of a < b is always false regardless of the value of the other number.
// the result is `b` when either a or b is NaN
#define min(a, b) (((a) < (b)) ? (a) : (b))
It can be desirable that the result is as below where "NaN arguments are treated as missing data". C11 Footnote #242
a NaN | b NaN | a < b | min
-------+---------+---------+---------------
No | No | No | b
No | No | Yes | a
No | Yes | . | a
Yes | No | . | b
Yes | Yes | . | either a or b
To do so with a macro in C would simple wrap the fmin() function which supprts the above table. Of course code should normally used the fmin() function directly.
#include <math.h>
#define my_fmin(a, b) (fmin((a), (b))
Note that fmin(0.0, -0.0) may return 0.0 or -0.0. They both have equal value.
If I were just trying to lightly obfuscate this I would probably go with something like:
#define min(a,b) ((a) + ((b) < (a) ? (b) - (a) : 0))
I think Doynax's solution is pretty cute, too. Usual reservations for both about macro arguments being evaluated more than once.
For slightly obfuscated, try this:
#define MIN(a,b) ((((a)-(b))&0x80000000) >> 31)? (a) : (b)
Basically, it subtracts them, and looks at the sign-bit as a 1-or-0.
If the subtraction results in a negative number, the first parameter is smaller.

Resources