【问题标题】:Checking the return value of a function in a macro检查宏中函数的返回值
【发布时间】:2010-02-01 15:29:01
【问题描述】:

我有核心功能,可以从产品的自定义模块中调用。

function_core 是核心函数,它将返回整数 我们在头文件中有一个宏:

#define func_cust function_core

我在打电话 func_cust 在我的自定义代码中。 但在核心内部,我们再次调用了其他一些核心函数:

 #define function_core main_core

所以我不能在我的自定义代码中放入所有参数。

我在许多 C 文件中调用了这个 func_cust 函数调用。

我需要检查函数function_core的返回值,比如 如果function_core 返回 x 那么我想将返回值更改为 0 否则将返回相同的返回值。

例如我想定义一个这样的宏:

#define funct_cust ((function_core==x)?0:function_core)

这可能吗?

更具体地说,这就是我需要的!

#include<stdio.h>

#define sum_2 ((sum_1==11)?0:sum_1)
#define sum_1(a,b) sum(a,b)
int sum( int ,int);

int main()
{
int a,b,c;
a=5;
b=6;
c=sum_2(a,b);
printf("%d\n",c);
}

int sum(int x,int y)
{
return x+y;
}

这给出了一个错误:

“test_fun.c”,第 12.3 行:1506-045 (S) 未声明的标识符 sum_1。

我只能玩这个宏 sum_2。

【问题讨论】:

  • 也许你应该显示你的function_core和main_core等的代码

标签: c unix macros c-preprocessor header-files


【解决方案1】:

最好写一个内联函数(C99支持这个):

static const int x = ...;
static inline int funct_cust(void* args) {
    int res = function_core(args);
    if (res == x) return 0;
    return res;
}

如果你使用gcc,可以使用statement exprs:

#define funct_cust(args) ({ int res = function_core(args); res == x ? 0 : res; })

【讨论】:

    【解决方案2】:

    如果你可以添加一个实际的功能,那就很容易了:

    int sanitize(int value, int x)
    {
      return (value == x) ? 0 : value;
    }
    

    然后把你的宏改成

    #define func_cust sanitize(func_core(), x)
    

    这解决了另一个棘手的问题,即不计算两次函数调用,也不必引入临时函数(这在宏中很难做到)。

    如果评估两次是可以的,那么当然就像你概述的那样做:

    #define func_cust  func_core() == x ? 0 : func_core()
    

    【讨论】:

      【解决方案3】:

      把它改成(假设a,b是常数)

      #define sum_2(a,b) ({(sum_1(a,b)==11)?0:sum_1(a,b);})
      #define sum_1 sum
      int sum(int ,int);
      

      这是不安全的,因为a,b 也可以是非常量表达式。因此,您可能希望创建保存 a,b 值的局部变量,以便它们只被评估一次 (改进)

      #define sum_2(a,b) ({                          \
          typeof(a) _a = (a);                        \
          typeof(b) _b = (b);                        \
          sum_1(_a, _b) == 11 ? 0 : sum_1(_a,_b);    \
      })
      #define sum_1 sum
      int sum(int ,int);
      

      不要遗漏任何花括号、最后一条语句中的分号和斜线。

      【讨论】:

        猜你喜欢
        • 2013-04-11
        • 2014-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-21
        • 2010-09-21
        • 2011-10-02
        • 1970-01-01
        相关资源
        最近更新 更多