简体   繁体   English

违反MISRA-2012规则20.12:misra_c_2012_rule_20_12_violation:扩展形式和原始形式均使用宏参数“ val”

[英]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: 我一直在面对这种MISRA违规行为:


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-2012报告违反规则20.12 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. MISRA-C认为在同一个宏中两次使用相同的预处理器常量是一个愚蠢的主意,在这种情况下,您可以在一种情况下扩展它,而在另一种情况下不扩展。

In your macro val##_MASK will not be expanded, so you get INIT_A_MASK . 在您的宏val##_MASK中将不会展开,因此您将获得INIT_A_MASK But later in the very same macro val is also expanded and replaced with ((A) | (1UL << 15)) . 但是稍后,在同一宏中, val也被扩展并替换为((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) ? 例如, #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. 不确定是否在任何情况下都行得通,当您输入“ if(!IS_STATE_IFSET(state,INIT_A))”时,INIT_A将立即扩展为其宏定义,并且该名称不会传递给IS_STATE_IFSET的定义首先。 I guess this is a case where your MISRA checker is behaving differently from a real C preprocessor. 我猜这是您的MISRA检查器的行为与真实C预处理程序不同的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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