简体   繁体   中英

MISRA-2012 Rule 20.12 violation: misra_c_2012_rule_20_12_violation: macro parameter “val” is used in both expanded and raw forms

I've been facing this MISRA violation:


Definitions:

#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 ?

Caller Details:

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

Misra-2012 reports Rule 20.12 violation misra_c_2012_rule_20_12_violation: macro parameter "val" is used in both expanded and raw forms

MISRA-C thinks it's stupid idea to use the same pre-processor constant twice in the same macro, where you have it expand in one case but not expand in another.

In your macro val##_MASK will not be expanded, so you get INIT_A_MASK . But later in the very same macro val is also expanded and replaced with ((A) | (1UL << 15)) .

The only acceptable solution is to rewrite all of this crazy code from scratch and get rid of all use of secret macro languages.

For example, just what is the meaning of #define A (1UL < 10) ? I assume << was intended. If not for the secret macro language, bugs like these are easy to find. But instead, you injected a hard-to-find dormant bug in your application.

Not sure if this can ever work in any case, when you write "if (!IS_STATE_IFSET(state, INIT_A))", the INIT_A will immediately be expanded into its macro definition, and the name will not be passed to the definition of IS_STATE_IFSET in the first place. I guess this is a case where your MISRA checker is behaving differently from a real C preprocessor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM