2015-03-19 2 views
1

Пока я вижу исходный код 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

Если возвращение функции является INT и типа ARG является символом, макро становится этой формой ,

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

Я не могу уловить роли двух аргументов до метода ovsrcu_postpone__.

+2

Это похоже на способ проверить совместимость типов 'FUNCTION' и' ARG' перед тем, как отбросить их типы (используя их в неоцениваемом выражении 'sizeof', которое ничего не делает во время выполнения, но которое должно пройти typechecker). Это своего рода «общее программирование». – Mankarse

ответ

3

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

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

1

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

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) будет расширен до трех комы разделенных выражений anclosed в скобках:

((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). Это тип проверки безопасности.

 Смежные вопросы

  • Нет связанных вопросов^_^