GNU C имеет два расширения, которые он предлагает для создания безопасных макросов, таких как MAX
и MIN
, которые будут оценивать аргументы только один раз: typeof
и __auto_type
. Приведем примеры двух макросов MAX
, демонстрирующих каждый из них:
#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; \
})
Проблема с обоими из них в том, что typeof
и __auto_type
выдают ошибки, если они используются в битовом поле. В этом примере кода показаны проблемы с битовым полем с использованием либо 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;
}
G CC дает следующие сообщения об ошибках для typeof
и __auto_type
соответственно:
error: 'typeof' applied to a bit-field
error: '__auto_type' used with a bit-field initializer
Итак, вопрос: почему G CC не позволяет использовать их с битовыми полями (я не могу найти по нему никакой документации) и что можно сделать, чтобы сделать макрос MAX
, который оценивает аргументы только один раз для любого типа, который все еще работает с битовыми полями?