【问题标题】:What meaning arguments before the function have?函数之前的参数有什么意义?
【发布时间】:2015-03-19 13:05:05
【问题描述】:

在查看 OVS 源代码时,我发现了非常奇怪的代码,这是我从未见过的。

https://github.com/openvswitch/ovs/blob/master/lib/ovs-rcu.h

void ovsrcu_postpone__(void (*function)(void *aux), void *aux);
#define ovsrcu_postpone(FUNCTION, ARG)                          \
    ((void) sizeof((FUNCTION)(ARG), 1),                         \
     (void) sizeof(*(ARG)),                                     \
     ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG))

我通过搜索得到了多参数sizeof的含义

Why call sizeof operator with two arguments? http://www.vxdev.com/docs/vx55man/diab5.0ppc/c-additi.htm#3001432

如果FUNCTION的返回是int,ARG的类型是char,宏变成这种形式。

((void) 4, (void) 1, ovsrcu_postpone__((void (*)(void *))(function), arg))

在 ovsrcu_postpone__ 方法之前,我无法捕捉到两个参数的作用。

【问题讨论】:

  • 这看起来像是一种在抛弃类型之前检查 FUNCTIONARG 类型兼容性的方法(通过在未评估的表达式 sizeof 中使用它们,这在运行时什么都不做,但必须通过类型检查器)。一种“通用编程”。

标签: c++ c openvswitch


【解决方案1】:

那么让我们看看他们在源代码中给出的例子:

ovsrcu_postpone(free, ovsrcu_get_protected(struct flow *, &flowp));

这将扩展为:

(
 (void) sizeof((free)(ovsrcu_get_protected(struct flow *, &flowp)), 1),
 (void) sizeof(*(ovsrcu_get_protected(struct flow *, &flowp))),
 ovsrcu_postpone__((void (*)(void *))(free), ovsrcu_get_protected(struct flow *, &flowp))
)

所以我们这里有一些类型安全,然后是预期的调用。以下是我可以梳理出的要求:

  • 第一个参数是一个有一个参数的函数。
  • 第二个参数至少有一个间接级别(它是一个指针)。

我们也可以这样理解:

 sizeof(free, 1);

这是使用逗号运算符,所以除了确保语法有效之外,它的返回值与sizeof(1) 相同。

【讨论】:

    【解决方案2】:

    从宏定义:

    void ovsrcu_postpone__(void (*function)(void *aux), void *aux);
    #define ovsrcu_postpone(FUNCTION, ARG)                          \
        ((void) sizeof((FUNCTION)(ARG), 1),                         \
         (void) sizeof(*(ARG)),                                     \
         ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG))
    

    我们可以推断ovsrcu_postpone(FUNCTION, ARG) 将扩展为三个用括号括起来的逗号分隔表达式:

        ((void) sizeof((FUNCTION)(ARG), 1),                         \ 1
         (void) sizeof(*(ARG)),                                     \ 2
         ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG))      \ 3
    

    逗号运算符从左到右计算表达式。所以这段代码将评估(void) sizeof((FUNCTION)(ARG), 1)(void) sizeof(*(ARG)) 并调用ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG)。这是一种安全检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 2011-12-19
      • 2017-02-08
      • 1970-01-01
      相关资源
      最近更新 更多