Какое значение имеют аргументы перед функцией?

Пока я смотрел исходный код 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, выполнив поиск

Зачем вызывать оператор sizeof с двумя аргументами? 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__.


person Hozard    schedule 19.03.2015    source источник
comment
Это похоже на способ проверить совместимость типов FUNCTION и ARG перед тем, как отбросить их типы (используя их в неоцененном выражении sizeof, которое ничего не делает во время выполнения, но которое должно пройти проверку типов). Этакое «универсальное программирование».   -  person Mankarse    schedule 19.03.2015


Ответы (2)


Итак, давайте посмотрим на пример, который они приводят в исходном коде:

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).

person Bill Lynch    schedule 19.03.2015

Из определения макроса:

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

Оператор Coma оценивает выражения, начиная слева направо. Таким образом, этот код будет оценивать (void) sizeof((FUNCTION)(ARG), 1) и (void) sizeof(*(ARG)) и вызывать ovsrcu_postpone__((void (*)(void *))(FUNCTION), ARG). Это вид проверки безопасности.

person 4pie0    schedule 19.03.2015