为了获得两个数中的最大值,我有以下宏
#define max(a,b) ((a) > (b) ? (a) : (b))
#define maxint(a,b) ({int _a = (a), _b = (b); _a > _b ? _a : _b; })
以上两者有什么区别。哪个更好用,为什么。 我找到了这些宏的信息 here .但无法理解。
最佳答案
第二个宏更安全,但使用了 GCC 提供的非标准 C 扩展:statement expressions .但第一个表达是“通用的”。使用 typeof GCC 的扩展将有助于:
#define mymax(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); \
_a > _b ? _a : _b; })
解决 JaredPar's answer 中提出的问题你可以使用预处理器 concatenation和 GCC 具体 __COUNTER__
(或者只是更标准的 __LINE__
),例如
#define mymax_counted(a,b,c) ({typeof(a) _a##c = (a); \
typeof(b) _b##c = (b); \
_a##c > _b##c ? _a##c : _b##c; })
#define mymax(a,b) mymax_counted(a,b,__COUNTER__)
但即使这样也不能完全防止失败(运气不好;如果唯一的 __COUNTER__
恰好是当时有 123 个)。
实际上,使用 inline function更好(因为如果你调用 mymaxfun(i++,t[i])
行为定义明确并且给出与 mymaxfun(t[i],i++)
相同的结果,并且因为优化编译器会产生与使用宏时一样高效的代码):
static inline int mymaxfun(int a, int b) { return (a>b)?a:b; }
遗憾的是,C 没有通用函数(考虑切换到 C++ 及其 templates 并使用 std::max );然而C11具有使用 _Generic
关键字的泛型表达式
宏很有用(如果掌握了),但是在调用宏(例如 mymax(i++,t[--i]++)
)时你应该非常小心参数中的副作用,所以你始终应该注意并记录 名称是宏还是其他名称(如函数)。根据经验,避免副作用 - 特别是 ++
或 --
以及许多其他 - 在函数调用查找表达式(函数调用和宏调用)中。
查看源代码的预处理器扩展形式;所以对于 foo.c
源代码,运行 gcc -C -E foo.c > foo.i
(添加任何预处理器选项,如 -I
, -D
等...是相关的)并查看 foo.i
例如使用 less foo.i
;它总是有启发性的。
关于c - 以下哪一个宏是安全的,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21300883/