Это расширение GCC.Оператор запятой не работает:
// C89, doesn't work...
#define max(a,b) \
(typeof (a) _a = (a), \
typeof (b) _b = (b), \
(_a > _b ? _a : _b))
Оператор запятой работает только с выражениями, а typeof(a) _a = (a);
является объявлением, а не выражением.На самом деле невозможно написать эквивалентный макрос без расширений GCC или C11, который имеет _Generic
.Обратите внимание, что typeof
также является расширением GCC, поэтому вы не получите никакой переносимости, исключив ({...})
, если не исключите также typeof
.
Вот версия C11, обратите внимание, насколько она многословна.сравнение (и оно обрабатывает только два типа!).C11 даже еще не поддерживается, удачи, пытаясь найти компилятор для проверки этого:
// C11
static inline int maxi(int x, int y) { return x > y ? x : y; }
static inline long maxl(long x, long y) { return x > y ? x : y; }
#define max(x, y) _Generic((x), \
long: maxl(x,y), \
int:_Generic((y), \
int: maxi(x,y), \
long: maxl(x,y)))
В переносимом C99 вы можете написать макрос или встроенную функцию, которая достигает того же эффекта, за исключением он будет работать только для одного типа на макрос.
// C99
static inline int maxi(int x, int y) { return x > y ? x : y; }
В C89 / C90 я не могу придумать, как написать макрос так, чтобы он не оценивался x
или y
дважды.