我最近发现了这个GCC宏:
#define max(a,b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
在我看到这段代码之前我没有意识到,代码块{...}
可以某种方式返回C中的值。
1)你能否给我一个暗示它是如何工作的?
尽管如此,我通常可以通过滥用逗号运算符来实现相同的结果:
#define max(a,b) \
(typeof (a) _a = (a), \
typeof (b) _b = (b), \
(_a > _b ? _a : _b))
或者如果它仅用于副作用,我会使用do { ... } while(0)
2)这样做的首选方式是什么?
答案 0 :(得分:10)
这是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
两次。
答案 1 :(得分:9)