GNU C has two extensions that it proposes to make safe macros like MAX
and MIN
that will evaluate arguments only once: typeof
and __auto_type
. To give examples of two MAX
macros demonstrating each one:
#define MAX(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b ? _a : _b; \
})
#define MAX(a, b) ({ \
__auto_type _a = (a); \
__auto_type _b = (b); \
_a > _b ? _a : _b; \
})
The problem with both of these is that typeof
and __auto_type
give errors if it is used on a bit field. This example code shows the problems with a bit field using either MAX
:
#include <stdio.h>
#include <stdint.h>
// Insert one of the MAX macros here
struct bitfields {
uint8_t a: 4;
uint8_t b: 4;
};
int main(int argc, char *args[]) {
struct bitfields x = {12, 4};
printf("%d\n", MAX(x.a, x.b));
return 0;
}
GCC gives these error messages for typeof
and __auto_type
, respectively:
error: 'typeof' applied to a bit-field
error: '__auto_type' used with a bit-field initializer
So the question is: Why does GCC not allow these to be used with bit fields (I can't find any documentation on it), and what can be done to make a MAX
macro that evaluates arguments only once for any type that still works with bit fields?
You use __typeof__(+(a))
to get the promoted type according to default promotions. This will work at least for bitfields of type int
. I'm not sure how compilers treat the type for larger bitfield types, which are implementation-defined.