Implementing min() and max() in Clang without double evaluation

Viewed 4581

The classic preprocessor version of the min function looks like

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

This leaves you open to double evaluation—the situation in which you do min(f(), g()), forgetting that f or g has side effects, and you have to spend hours trying to figure out why your function is running twice. To prevent this, you can do

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

This works great under GCC, but if you run it through Clang with -Wgnu set—this set of warnings falls under the umbrella of -pedantic—you get errors like

test.c:5:10: error: use of GNU statement expression extension [-Werror,-Wgnu]
        int a = min(3, 7);
                ^
test.c:1:22: note: expanded from macro 'min'
#  define min(a, b) ({__typeof__(a) _a = (a); __typeof__(b) _b = (b); _a < _b ? _a : _b;})

Is it possible to define these macros in a way that prevents double evaluation and which is acceptable to Clang under -pedantic? (Yes, you can disable the warning with -Wno-gnu, in which case Clang handles the statement expression without a problem. I’m asking because I, like clang -pedantic, am too picky for my own good.)

Edit: I am working in C. I tagged this C++ too because I thought a solution might apply to C++ as well as to C. Oops—forgot about templates! Sorry for the ambiguity.

3 Answers
Related