[英]Checking function calls are not passed as arguments (C macros)
在一个我从事的项目中,我们有一些实用程序宏,它们多次引用它们的参数。
让我们使用一个简单的示例:
#define ABS(a) ( (a) < 0 ? (-(a)) : (a) )
现在这是一个庞大的代码库,在我们回顾代码的同时,我时不时地发现一个函数调用被传递给宏。 这不是一个错误 ,但是它意味着函数调用被多次执行,而我通常不希望这样做。
在这种情况下,我们至少可以用fabsf
, fabs
, abs
代替float
/ double
/ int
,但是让我们假设并非总是有好的内置替代方法,并且宏将保留为宏。
例:
f = ABS(dot_v3v3(vel, sp));
/* expands into */
f = ( ( dot_v3v3(vel, sp) ) < 0 ? (-( dot_v3v3(vel, sp) )) : ( dot_v3v3(vel, sp) ) );
所以我的问题是:
可以检测到宏内使用的函数调用(警告或错误)吗?
这是我已经检查过的一些内容...
这将导致函数调用无法编译,但有一个缺点,如“ 1”之类的常量也会给出错误以及诸如(b-c)之类的表达式。
#define ABS(a) ((void)((&a) == (&a)), ( (a) < 0 ? (-(a)) : (a) ))
注意:我发现指出某些错误的宏用法已经很方便了,但是由于它具有假阳性,因此不能保留。
使用_Generic
,您可以将C宏转换为内联函数的包装。 这意味着在宏中多次调用函数的问题就消失了。
#define ABS(a) \
_Generic((a), \
long double: my_abs_double(a), \
float: my_abs_float(a), \
int: my_abs_int(a) \
/* ... and so on, char, long, short... etc */ \
)
这不是一个可行的解决方案-我们仍然支持不支持泛型的编译器。
我确实在MirOS C预处理程序手册的重复副作用部分找到了这个技巧:
#define min(X, Y) \
({ typeof (X) x_ = (X); \
typeof (Y) y_ = (Y); \
(x_ < y_) ? x_ : y_; })
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.