Why the macro value is 0 instead of 1? - c

here base->left is NULL, and base->right->height is 0:
((((base->left ? base->left->height : -1)) > ((base->right ? base->right->height : -1)))
?
((base->left ? base->left->height : -1) + 1)
:
((base->right ? base->right->height : -1) + 1))
IMO the result of the above expression should be 1,
but it turns out it's 0 when I print it out.
Anyone knows the reason?
Is it a bug of gcc 4.3.2?
UPDATE
how the expression come?
#define MAX_PLUS_1(a, b) (((a) > (b)) ? (a + 1) : (b + 1))
#define BINARY_TREE_HEIGHT(node) (node ? node->height : -1)
#define BINARY_TREE_SYN_HEIGHT(left, right) \
MAX_PLUS_1(\
BINARY_TREE_HEIGHT(left),\
BINARY_TREE_HEIGHT(right)\
)
it's really BINARY_TREE_SYN_HEIGHT(base->left, base->right)
And the problem is gone if I replace MAX_PLUS_1 with function:
int MAX_PLUS_1(int a, int b){
return (((a) > (b)) ? (a + 1) : (b + 1));
}

Your code is badly designed. The fact that it works as a function, let me just suspect that this comes from the multiple evaluation of your macro arguments.
don't ever have macros that evaluate their arguments twice. If the argument has side effects you are screwed
always put parenthesis around your macro arguments. Depending on the arguments when called, operator precedence may give you something quite different than you think
whenever this is possible simply use an inline function instead of a macro. This is as efficient, has type checking and guarantees that arguments are only evaluated once.
in your particular case there is no reason at all to have the +1 inside the macro. Factor it outside the macro or function call.
you don't seem to control the types that you are using very well. you say your height field is an unsigned type but you give us a function call that has int parameters.
Edit: usually uint32_t is not well suitable as an application type. why 32 bit why not 64? The best standard unsigned type for "sizes", "length" and stuff like that is usually size_t. Let the system decide what type it handles best.

From additional information in our Comments discussion, your height field is unsigned. That means that when you try to compare it to -1 you end up in trouble - (uint32_t)-1 == 0xFFFF_FFFF = Very Big Number, so the 'left' branch gets chosen over the 'right' branch at some point when you don't expect it to.
Writing MAX_PLUS_1() as a function solves, or perhaps rather hides, this problem because you use int for the parameters. That means the comparison is done between the height value and (int)-1, which is what you wanted.

The problem is your variables aren't what you think they are.
If you replace those with values to test the ternary, it indeed prints 1
((((0 ? 1 : -1)) > ((1 ? 0 : -1)))
?
((0 ? 0 : -1) + 1)
:
((1 ? 0 : -1) + 1));

Related

Sending parameter to a #define

I wonder to know is it possible to send a parameter to a #define macro for selecting different output
For example:
#define Row(1) LPC_GPIO0
#define Row(2) LPC_GPIO3
#define Row(3) LPC_GPIO2
Then in my code I create a loop for sending the parameter
Row(x)
This macro syntax doesn't exist.
Moreover, it can't possibly exist, because macros are expanded before the compiler compiles the code. If your x isn't a compile time constant, there would never be a way to determine what to replace in the source code for the macro invocation.
If you need to index some values, just use an array, e.g. (assuming these constants are integers):
static int rows[] = { 0, LPC_GPIO0, LPC_GPIO3, LPC_GPIO2 };
Writing
rows[x]
would have the effect you seem to have expected from your invalid macro syntax.
if you want to use macros
#define GPIOx(x) GPIO##x
and GPIOx(1) will expand to GPIO1
If you want these calculated at runtime there is a way to do what you want
#define Row(x) (x == 1 ? LPC_GPIO0 : (x == 2 ? LPC_GPIO3 : (x == 3 ? LPC_GPIO2 : ERROR_VALUE)))
Though this gets messy as the number of options increases
Also, even if you do want this evaluated at compile time, most optimizing compilers would do that for you as long as x is a constant

Why am I getting the answer "odd" instead of "even"

Why am I getting the answer "odd" instead of "even"?
#include<stdio.h>
#define ODD(x) x%2?0:1
int main()
{
int a=5;
if(ODD(a+1))
printf("even");
else
printf("odd");
return 0;
}
ODD(a+1) expands to a+1%2?0:1. With a as 5, that is same as (5+(1%2))?0:1 or 0.
% beats + which beats ?:
if(0)
printf("even");
else
printf("odd"); // print `odd`
Perhaps you wanted some () to insure evaluation order.
// #define ODD(x) x%2?0:1
#define ODD(x) ((x)%2?0:1)
Yet that seems backwards. How about
#define ISODD(x) ((x)%2 != 0)
See How do I check if an integer is even or odd?
1 is treated as true and 0 as false.
if (1) is executed always, and when you get 0 as result, the branch shifts to else
so code should be :
if ODD is true (returning 1 from terneray expression), print "odd"
#define ODD(x) x % 2 ? 0 : 1
Given an even number x, x % 2 will give you zero, which is false.
Hence the result of the entire ternary expression will be the second option 1, which is true.
You would be better off with something like:
#define ODD(x) (((x) % 2) != 0)
It's both more readable in intent, and less prone to errors such as getting the true/false values mixed up, or being burnt by simple text substitution having unexpected effects.
I do not like this kind if macros for many reasons (one of it that they can be a source of silly errors - like in your case). It should be domain of functions.
int ODD(int x)
{
return x & 1;
}
if you are worried about function call overhead just make it inline (but on any level op optimisation the compiler will inline it anyway as the call is probably longer than the function itself.

Error in C code error: expression is not assignable

I'm writing a function that is suppose to print out the description of a programs execution. A function in my program uses 0 as a signal for a base-10 numeric conversion.
I would like my program to have friendly output, and tell the user if a number has been converted to base 10, instead of letting the program say the number was converted from base 0.
When I attempt to compile this code, I get an error message which says 'expression is not assignable'.
I'm compiling on command line with cc compiler
Apple LLVM version 7.3.0 (clang-703.0.29)
Any idea what this error means and how to correct?
Thanks.
void foo( int base ){
int theBase;
base == 0 ? theBase = 10: theBase = base;
printf("%s%d\n", "The base is ", theBase)
}
error message:
error: expression is not assignable
base == 0 ? theBase = 10: theBase = base;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
What you are doing here is a conditionnal assignation.
Usually you can do it like that:
if (base == 0)
theBase = 10;
else
theBase = base;
Here you chosed to use a ternary expression. It does work a bit like an if/else structure, but it is really different.
The ternary return a value, it's not made to execute code based on a condition. No, it return a value based on a condition.
So here, you have to do:
theBase = (base == 0 ? 10 : base);
(the parenthesis are not required, but it's a lot better to avoid error).
In fact, you can make a ternary execute code, in a multiple way, like returning a function:
int my_function()
{
printf("Code executed\n");
return (10);
}
/* ... */
theBase = (base == 0 ? my_function() : base);
EDIT:
And yes you can use that code:
base == 0 ? (theBase = 10) : (theBase = base);
But it's pretty useless to use a ternary in that case, because you still have to duplicate the theBase = X code.
Because you need the lvalue, where it belongs, at the left side of the expression, like this
theBase = (base == 0) ? 10 : base;
Note how the compiler considers
base == 0 ? theBase = 10 : theBase
like the "lvalue" in that expression, because of operator precedence.
The ternary operator, is that, an operator, so you can't use it to replace an if statement.
You should use
theBase = (base == 0 ? 10 : base);
instead of
base == 0 ? theBase = 10: theBase = base;
You have to put parenthesis around the assignments
base == 0 ? (theBase = 10) : (theBase = base);
else priority is playing tricks on you. Even better, use the idiomatic syntax:
theBase = base ? base : 10;
Not answering the question, but might be helpful for others who encountered this:
In my case I had legal assignment, like:
int xyz = 5;
I was not aware that somewhere in the included headers there was the following line:
#define xyz 14
I'm not sure why the compiler didn't shout about syntax error before this semantic one. Either way if someone is frustrated enough to reach this answer I would recommend to check if the variable name is not already defined somewhere before as a macro or similar.

When is (x || !x) false?

A friend of mine jokingly asked me this question. It was meant to be a "goes without saying" type remark, but then I actually thought about it for a while and started coming up with some clever "almost solutions".
First attempt:
If C ever supports quantum computing there may be an answer to this. A q-bit can be in many states at once, so it could be false AND true and this conditional will return (BOOL)0.5 aka "Yes/no/maybe-so" - but once you observe the variable the whole thing will collapse and become invalid again.
Second attempt:
If X could somehow be defined as a random binary generator and you cast it to a BOOL you could get false some of the time. I'm not sure if you can do this though in C unless you use CLANG. #define x (BOOL)!!(rand()%2)
The language we were discussing this in is C but I'm also curious if anyone can find any solutions in any language.
When x is volatile (volatile int x) and is modified by an external thread / device, the expression can be false.
It's a bit of a trick, but the following solution also works:
#define x 1 ? 0 : 1
(x || !x)
The reason is in the operator precedence. After preprocessing (x || !x) resolves to the following (parentheses added to show the precedence):
(1 ? 0 : (1 || !1) ? 0 : 1)
Macros are really cheating here, but you don't need anything to do with boolean types or special compilers. The following, as far as I know, is legal standard C.
#include <stdio.h>
int f(void) {
static int y = 0;
if (y == 0) {
y = 1;
return 0;
} else {
return 1;
}
}
#define x f()
int main(void) {
if (x || !x) {
puts("It was true");
} else {
puts("It was false");
}
return 0;
}
Or even more concisely:
int y = 0;
#define x y++
(For those worried about undefined behavior, note there is a sequence point between the left and right side of ||.)
An even simpler macro:
#define x 0&0
expanding (x || !x) gives (0 & 0 || !0 & 0) which is always false.
Similarly:
#define x 0*0
#define x 1*0 // for binary buffs
#define x 4&2 // for HHGG fans.
I could not find a 2 letter macro :(
Tried in JS:
var i = 0
i++ || !(i++)
Note: this solution works only when i = 0

Output: relational and ternary operator?

#include<stdio.h>
main()
{
int big,x=3,y=2,z=1,q=4;
big=( x>y ? (x<z ? 20:10 && y>x ? 50:10 ) : (y>z ? 40:10 || x<q ? 30:10));
printf("big =%d",big);
return 0;
}
&& is a relational operator so it should return a true or false value i.e 0 or 1, but in this case its not. Please explain whats the logic behind its output?
Output: big =10
It's all about operator precedence (and a distressing lack of parentheses).
The output I get when I run your program is nbig =10 (with no newline; you should add a \n to your format string).
The value assigned to big isn't the result of an && or || operator. Let's reduce that over-complicated expression, one step at a time. (I've confirmed at each step that the result is unchanged.)
big=(x>y?(x<z?20:10 && y>x?50:10) : (y>z?40:10 || x<q?30:10));
We know that x>y is true, so we can drop the test and the third operand of the corresponding ?: operator:
big=(x<z?20:10 && y>x?50:10);
Let's remove the extraneous outer parentheses, add some new around the third operand of the outer ?: operator, and change the spacing a bit:
big = x<z ? 20 : (10 && y>x?50:10);
We know that x<z is false, so we can drop that and the second operand of the outer ?::
big = (10 && y>x?50:10);
Obviously 10 is true, so:
big = (y > x ? 50 : 10);
And y > x is false, so the result is 10 -- which is what I get when I run your program.
You probably assumed that this:
a ? b : c && d ? e : f
is equivalent to:
(a ? b : c) && (d ? e : f)
but in fact it's equivalent to:
a ? b : ((c && d) ? e : f)
because the && operator binds more tightly than the ?: operator.
In any case, if this is real code, you should definitely add enough parentheses so that a reasonably knowledgeable reader can understand the code without having to consult an operator precedence table. Mixing &&, ||, and ?: can be particularly confusing. Breaking down the expression into subexpressions, and assigning each one to a temporary variable (so it has a meaningful name) can also be helpful.
The above applies if you're trying to write a complex expression. If you're trying to understand something that someone else has written, you pretty much have to parse it yourself. Try doing what I did: incrementally simplify the expression (by removing parts or adding parentheses) in ways that don't change the meaning, confirming at each step that you get the same result. And if it's production code (rather than a quiz, which this appears to be), consider complaining bitterly encouraging the author to write clearer code.
Let's make your expression a bit more explicit by adding parethesis to show the precedence:
((x>y) ?
((x<z) ?
20 : ((10 && (y>x)) ? 50 : 10)
) : (
(y>z)?40:((10 || (x<q))?30:10)
)
)
x is greater than y, so let's consider
((x<z) ?
20 : ((10 && (y>x)) ? 50 : 10)
)
and x is not less than z, so
((10 && (y>x)) ? 50 : 10)
y is not greater than x, so
10
You can see that the results are not actually of your logical operators. Because of the complexity involved, you should almost certainly express such an evaluation using if statements to break up the logic in a clean way.

Resources