Wrong number macro

I don't understand why the following code prints 2 instead of 1 ...

#include <stdio.h> #define ABS(x) ((x) < 0) ? -(x) : (x) int main() { printf("%d", ABS(ABS(-2)-(ABS(-3)))); return 0; } 

This question was on our exam, and I answered that the result is 1, but after compilation I get 2 ... Someone please explain what the expression actually does ... Thanks in advance.

+6
source share
6 answers

There is a problem with parentheses. If you expand the macro, you will get complex nested three-dimensional operations that will be calculated to 2 (see. Extension in the update). Surround the macro with brackets to get the result you want.

Refresh . Manual extension:

 ABS(ABS(-2)-(ABS(-3))) 

expands to:

 ((ABS(-2)-(ABS(-3))) < 0) ? -(ABS(-2)-(ABS(-3))) : (ABS(-2)-(ABS(-3))) 

ABS(-3) is surrounded by parentheses everywhere, so it is safely rated 3 , so there is no need to expand it. So we are done:

 (( ((-2) < 0) ? -(-2) : (-2) - 3) < 0) ? -(ABS(-2)-3) : (ABS(-2)-3) 

(ABS(-2)-3) will expand to

 ((-2) < 0) ? -(-2) : (-2) - 3 = 2 

Score for everything: (( true ? 2 : -5 < 0) ? -2 : 2 or

(2 < 0) ? -2 : 2 = 2 (2 < 0) ? -2 : 2 = 2 And this is the observed result, I hope that this is doable.

which is eno

+2
source

You forgot the outer bracket, try the following:

 #define ABS(x) (((x) < 0) ? -(x) : (x)) 
+3
source
 #include <stdio.h> #define ABS(x) ((x) < 0) ? -(x) : (x)) int main() { printf( "%d", ABS( ABS(-2) - ABS(-3) ) ); return 0; } 

You forgot the closing right bracket ) in your #define .

In addition, return must be lowercase

I put spaces so you can see the grouping more clearly.

+1
source

at http://coliru.stacked-crooked.com/a/59700f453a1dcaf9 with the -E compilation option

The gcc preprocessor solved the following:

 printf("%d\n", ABS(ABS(-2)-(ABS(-3)))); 

:

 printf("%d\n", ((((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) < 0) ? -(((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) : (((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3)))); 

check it out yourself

+1
source

You need to copy around the expression that the ABS defines. Instead

 #define ABS(x) ((x) < 0) ? -(x) : (x) 

you need:

 #define ABS(x) (((x) < 0) ? -(x) : (x)) ^----------------------^ 

Without this, the expression ABS(ABS(-2)-(ABS(-3))) expands to:

 ((((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) < 0) ? -(((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) : (((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ? -(-3) : (-3))) 

It will not be easy to analyze to understand what went wrong. However, if you look at the beginning of the expression, you will see that the first term runs through the second term.

 ((-2) < 0) ? -(-2) : (-2)-(((-3) < 0) ... ^^ (-2) Runs into the next term 

The meaning of the expression is difficult to predict. If you add brackets around the expression that defines the macro, you will see:

 ( (((-2) < 0) ? -(-2) : (-2)) - ( (((-3) < 0) ... ^ ------ one term ------- ^ There is no running in to the next term. 
+1
source

Let me expand this macro manually:

 ABS(-3) == ((-3) < 0) ? -(-3) : (-3) ABS(-2) == ((-2) < 0) ? -(-2) : (-2) ABS(-2) - ABS(-3) == ((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3) 

Now we have a problem: binary - has a higher priority than ?: So the above is parsed as:

 ((-2) < 0) ? -(-2) : ((-2) - ((-3) < 0) ? -(-3) : (-3)) 

Since (-2) < 0 true, we evaluate -(-2) . Then:

 ABS( ABS(-2) - ABS(-3) ) == ((((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3)) < 0 ? -(((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3)) : (((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3)) 

We have already established that

 ((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3) 

has a value of 2 , so the expression

 (((-2) < 0) ? -(-2) : (-2) - ((-3) < 0) ? -(-3) : (-3)) 

estimated, and guess what? He rates a value of 2 .

What you need to do is change your macro as follows:

 ABS(x) ( (x) < 0 ? -(x) : (x) ) 

Then everything expands as

 ABS(-3) == ((-3) < 0 ? -(-3) : (-3)) ABS(-2) == ((-2) < 0 ? -(-2) : (-2)) ABS(-2) - ABS(-3) == ((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3)) ABS(ABS(-2) - ABS(-3)) == (((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3)) < 0 ? -(((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3))) : ((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3)) 

This time

 (((-2) < 0 ? -(-2) : (-2)) - ((-3) < 0 ? -(-3) : (-3)) 

evaluated to -1 .

The rest should be clear here.

You should always wrap the body of macro expressions in an outer pair of parentheses for this reason.

+1
source

All Articles