MISRA违规规则10.1和枚举
首先,这类似于: 如何隐式转换整数类型? 但是有一个不同的MISRA警告。
编译器不会生成MISRA错误,但静态分析工具会生成错误。 我正在与正在进行的工具制造商订票。
鉴于:
#include enum Color {RED, VIOLET, BLUE, GREEN, YELLOW, ORANGE}; int main(void) { enum Color my_color; my_color = BLUE; if (my_color == YELLOW) // Generates MISRA violation, see below. { printf("Color is yellow.\n"); } else { printf("Color is not yellow.\n"); } return 0; }
静态分析工具正在为if
语句生成MISRA违规:
MISRA-2004 Rule 10.1 violation: implicitly changing the signedness of an expression. Converting "4", with underlying type "char" (8 bits, signed), to type "unsigned int" (32 bits, unsigned) with different signedness.
编译器是正确的(不是识别缺陷)还是静态分析工具?
根据C语言规范,表达式的类型:
typedef enum Colors {RED, VIOLET, BLUE, GREEN, YELLOW, ORANGE} Colors_t;
是一个signed int
。
同样根据语言,枚举项的值是可以包含整个枚举的最小单位。 所以在上面的枚举中, BLUE
的类型为signed char
。
当将Colors_t
变量与BLUE
进行比较时,静态分析工具会报告MISRA违规:
Colors_t my_color; if (my_color == BLUE) // This generates a MISRA violation.
与signed char
相比,违规是signed int
。
此外,枚举项可以与其他枚举类型混合而不会出错, 因为枚举不是唯一类型 :
typedef enum Tree_Species {REDWOOD, CYPRUS, PALM, OAK, JUNIPER, SEGUARO} Tree_Species_t; Tree_Species_t my_tree; my_tree = BLUE;
似乎某人(您的编译器或静态工具)认为您的枚举与int的大小和/或签名不同。
我的Green Hills编译器有一个选项–short-enum(使用最小类型可能为枚举),它将为上面的示例选择一个char类型。 你的编译器有这样的选择吗? 它启用了吗? 编译器默认枚举为“非标准”值吗?
根据我的经验,默认情况下,静态工具默认遵循语言规范,这意味着它应该期望枚举为int大小。 (参见此链接以供参考: C中枚举的大小是多少? )。 由于大多数静态工具都会窥探您的编译器命令行用法,因此您的编译时选项可能会使静态分析器确信您的枚举小于整数 。
我建议彻底检查您的编译器和静态分析器文档以解决冲突。 密切关注构建过程(编译时选项,默认值等)。
这可能是my_color
声明的my_color
enum Color my_color;
尝试从中删除“枚举”:
Color my_color;
静态分析器可能会认为您正在声明一个单独的枚举,因此10.1违规。 由于它的类型不同,MISRA规则禁止将一种类型分配给另一种类型。