Ответ 1
полный отрывок из соответствующего файла:
#if !defined(CONFIG_PREEMPT_RT) && ( defined(CONFIG_PREEMPT) ||
(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) )
#define can_preempt_disable preempt_disable
#define can_preempt_enable preempt_enable
#else /*CONFIG_PREEMPT*/
#define can_preempt_disable() do { } while (0)
#define can_preempt_enable() do { } while (0)
#endif /*CONFIG_PREEMPT*/
Таким образом, первая часть - это код, который вы получаете, когда вы запрашиваете защиту от упреждения, иначе вы получите пустые, не-ничего, циклы.
Я предполагаю, что они написаны так по обычным причинам, то есть для обеспечения того, что макрос все еще является допустимым оператором.
В определении не должно быть конечной точки с запятой, так как это будет в коде с использованием этих, например эта функция, которая начинается:
int c_can_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
{
can_preempt_disable();
...
Итак, очевидно, что макрос используется как любой другой вызов функции, а точка с запятой находится прямо там, где вызывается макрос. Это очень нормально.
ОБНОВЛЕНИЕ 2. Определение его на ;
приводит к двойным точкам с запятой, что является уродливым, по крайней мере, на мой взгляд. Пустая цепочка , я думаю, но эта конструкция {}
будет работатьdo/while
еще более идиоматична, поскольку она часто используется в таких случаях.
ОБНОВЛЕНИЕ 3. Как указано в комментарии, пустая пара скобок не будет работать, так как после вызова вы не сможете поставить точку с запятой. Ааа. Спасибо!