检查函数调用不作为参数传递(C宏)
发布时间:2020-12-16 03:05:05 所属栏目:百科 来源:网络整理
导读:在我工作的一个项目中,我们有一些实用程序宏,多次引用他们的参数. 让我们使用一个简单的例子: #define ABS(a) ( (a) 0 ? (-(a)) : (a) ) 现在这是一个很大的代码库,而在我们检查代码的时候,我现在发现一个函数调用被传递给一个宏. 这不是一个错误,但这意味
在我工作的一个项目中,我们有一些实用程序宏,多次引用他们的参数.
让我们使用一个简单的例子: #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_; }) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |