Нарушение правила 20.12 MISRA-2012: misra_c_2012_rule_20_12_violation: параметр макроса "val" используется как в расширенном, так и в необработанном виде - PullRequest
0 голосов
/ 23 мая 2019

Я столкнулся с этим нарушением MISRA:


Определения:

#define A                 (1UL << 10)
#define INIT_A            ((A) | (1UL << 15))
#define INIT_A_MASK       (0xFFFFUL << 15)


#define IS_STATE_IFSET(state, val)  ((((state) & (val##_MASK)) == (val)) ? true : false)   //issue is here ?

Информация о звонящем:

uint64_t state = 1234UL;
if (!IS_STATE_IFSET(state, INIT_A)) {
    printf("Hoo-Haa\n");
}

Misra-2012 сообщает о нарушении правила 20.12 misra_c_2012_rule_20_12_violation: macro parameter "val" is used in both expanded and raw forms

Ответы [ 2 ]

2 голосов
/ 23 мая 2019

MISRA-C считает глупой идею использовать одну и ту же константу препроцессора дважды в одном и том же макросе, где она расширяется в одном случае, но не расширяется в другом.

В вашем макросе val##_MASK не будет расширен, поэтому вы получите INIT_A_MASK. Но позже в том же макросе val также расширяется и заменяется на ((A) | (1UL << 15)).

Единственное приемлемое решение - переписать весь этот сумасшедший код с нуля и избавиться от всякого использования секретных языков макросов.

Например, что означает #define A (1UL < 10)? Я предполагаю, что << был предназначен. Если бы не секретный макроязык, такие ошибки легко найти. Но вместо этого вы внедрили трудно обнаруживаемую ошибку в ваше приложение.

0 голосов
/ 23 мая 2019

Не уверен, может ли это когда-либо работать в любом случае, когда вы пишете «if (! IS_STATE_IFSET (state, INIT_A)))», INIT_A будет немедленно расширен в определение макроса, и имя не будет передано определение IS_STATE_IFSET в первую очередь. Я предполагаю, что это тот случай, когда ваша программа MISRA ведет себя не так, как настоящий препроцессор C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...