# Artificial truth

## The more you see, the less you believe.

[archives] [latest] | [homepage] | [atom/rss]

# MIN and MAX macro considered harmful Tue 17 February 2015 — download

This is one of my favourite interview question: What is wrong with this macro ?

```#define MIN(a, b) ((a) < (b)) ? (a) : (b)))
```

I mean, it's in the GNU libc, so it should be pretty good:

```grep MIN /usr/include/sys/param.h
#define MIN(a,b) ((a)<(b))?(a):(b))
\$
```

Let me show you

```#include <stdio.h>

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

int main() {
int a = 1, b = 2;
printf ("%d\n", min (a, b));
printf ("a=%d, b=%d\n\n", a, b);

printf ("%d\n", min (a++, b++));
printf ("a=%d, b=%d\n\n", a, b);
}
```
```\$ gcc test.c && ./a.out
1
a=1, b=2

2
a=3, b=3

\$
```

It's a classic trick: Double evaluation.

This is why cool kids are using this macro:

``` #define MIN(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })
```

or even this one

```#define MIN(x,y) ({ \
typeof(x) _x = (x);     \
typeof(y) _y = (y);     \
(void) (&_x == &_y);    \
_x < _y ? _x : _y; })
```

Unfortunately, it's using some cancer GNU extension; there is no way in ANSI C to get the type of a variable.

Of course, you could hardcode them (Or pass them as arguments, but this would be annoying (and you'll likely end using the GNU-specific statement as expressions extension, or worse, the blocks one)):

```#define MIN(a,b) \
({ int _a = (a); \
int _b = (b); \
_a < _b ? _a : _b; })
```

But since you're losing macro's genericity, you might as well use an inline function like this one

```inline int min(int a, int b) {
if (a > b)
return b;
return a;
}
```

Long story short: Don't use macro for `MIN` and `MAX` in C, because you'll use them one day with a side-effect argument, and then, Smokey, my friend, you will be entering a world of pain.

edit: It seems that this blogpost may make its way into cppcheck ;)