Amit Sharma
Amit Sharma

Reputation: 2067

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

Upvotes: 0

Views: 688

Answers (2)

Richard at ImageCraft
Richard at ImageCraft

Reputation: 665

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.

Upvotes: -1

Lundin
Lundin

Reputation: 213872

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

Upvotes: 2

Related Questions