检查函数调用不作为参数传递(C宏)

 手机用户2702933093 发布于 2023-02-13 16:40

在我工作的项目中,我们有一些实用程序宏,它们多次引用它们的参数.

让我们用一个简单的例子:

#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 */ \
        )

这还不是一个可行的解决方案 - 我们仍然支持不支持泛型的编译器.

1 个回答
  • 我在MirOS C预处理器手册的重复副作用部分找到了这个技巧:

     #define min(X, Y)                \
     ({ typeof (X) x_ = (X);          \
        typeof (Y) y_ = (Y);          \
        (x_ < y_) ? x_ : y_; })
    

    2023-02-13 16:43 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有