-2

I tried with this macro:

#define min(x,y) x<y? x:y

It's supposed to return the minimum and it does. The only problem is when trying to use the result of that macro in an operation, it doesn't work.

Example

x=min(3,4);

Here x will naturally have 3 as a value, but when trying this:

x= 23 + min(3,4);

the result will still always be 3 (the result of the macro), no matter what number I add to it (23 was arbitrary in there). May I know why this happens?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
J doe
  • 9
  • 1

4 Answers4

2

min should be defined as:

#define min(a,b)  (((a) < (b)) ? (a) : (b))

You also seem to be mixing MIN and min. C is case sensitive, so min() could be calling something else.

#define min(X,Y) X<Y? X:Y  // I changed MIN to lowercase here
x= 23 + min(3,4);

-> will expand to:

x = 23 + 3 < 4 ? 3 : 4;

which is the same as:

x = (23 + 3) < 4 ? 3 : 4;

That's why parentheses are needed:

x = 23 + ((3 < 4) ? 3 : 4);

To avoid further problems with for example: min(x | b + 4 / 2, y && 0x01 + 3);, parentheses are added around all the values:

(((a) < (b)) ? (a) : (b))

When using such macro's, care should be taken with the following:

int y = 1;
int z = 2;

x = min(y++, z++);

This evaluates to:

x = ((y++ < z++) ? y++ : z++); // some parentheses omitted

Which is not wat we want. y or z will be incremented twice.

Danny_ds
  • 11,201
  • 1
  • 24
  • 46
2

The problem is operator assocativity and precedence. When you expand the macro, it becomes:

x = 23 + 3 < 4 ? 3 : 4;

which is interpreted as:

x = (23 + 3) < 4 ? 3 : 4;

because arithmetic has higher precedence than comparison operators. You should wrap the expansion in parentheses to force it to be treated as a single expression.

#define min(x,y) (x<y? x:y)

You should also put parenthese around the uses of each parameter, in case they're expressions with operators that have lower precedence than <.

#define min(x,y) ( (x) < (y) ? (x) : (y) )

DEMO

But using a macro for a function like this is still a bad idea. All the repetitions of the parameters mean that you can't use it with expressions with side effects. E.g. min(i++, j++) will increment one of the variables twice. It would be better to use an inline function.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

This is a good example of why parenthesis in macros is important.

This:

x= 23 + min(3,4);

Expands to this:

x= 23 + 3<4? 3:4;

Which, with implicit parenthesis, is the same as:

x= ((23 + 3)<4)? 3:4;

This evaluates to 4.

If you define your macro like this:

#define min(x,y) ((x)<(y)?(x):(y))

Then you get this:

x= 23 + ((3)<(4)?(3):(4));

The ternary evaluates to 3, so x is assigned 26.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

It's because + has the highest precedence, < is next and ? has the lowest precedence. So,

23 + min(3,4)

expands to

23 + 3 < 4 ? 3 : 4

So, the addition is done first, and then you'd have:

26 < 4 ? 3 : 4 

Then the relational operator is done, and you'd have:

0 ? 3 : 4

So, you should actually be getting 4 as the result.

bruceg
  • 2,433
  • 1
  • 22
  • 29