让我们使用一个简单的例子:
#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) ))
注意:我发现这已经非常方便地指出了一些坏的宏使用,但由于它具有假阳性,它不能被留下.
C11泛型
使用_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 Preprocessor manual in the section on duplicating side effects中找到了这个技巧:#define min(X,Y) \ ({ typeof (X) x_ = (X); \ typeof (Y) y_ = (Y); \ (x_ < y_) ? x_ : y_; })总结
以上是内存溢出为你收集整理的检查函数调用不作为参数传递(C宏)全部内容,希望文章能够帮你解决检查函数调用不作为参数传递(C宏)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)