问题
First off, this is similar to: How are integer types converted implicitly? but with a different MISRA warning.
The compiler does not generate a MISRA error, but the static analysis tool does. I have a ticket with the tool manufacturer in progress.
Given:
#include <stdio.h>
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;
}
The static analysis tool is generating a MISRA violation for the if
statement:
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.
Is the compiler correct (not identifying the defect) or the static analysis tool?
回答1:
Per the C language specification, the type of the expression:
typedef enum Colors {RED, VIOLET, BLUE, GREEN, YELLOW, ORANGE} Colors_t;
is a signed int
.
Also according the language, the value of an enumerated item is the smallest unit that can contain the entire enumeration. So in the above enumeration, BLUE
has the type signed char
.
The static analysis tools are reporting a MISRA violation when a variable of Colors_t
is compared to BLUE
:
Colors_t my_color;
if (my_color == BLUE) // This generates a MISRA violation.
The violation is signed int
compared to signed char
.
Also, the enumeration items can be mixed with other enumeration types without error, since the enumerations are not a unique type:
typedef enum Tree_Species {REDWOOD, CYPRUS, PALM, OAK, JUNIPER, SEGUARO} Tree_Species_t;
Tree_Species_t my_tree;
my_tree = BLUE;
回答2:
It appears that someone (your compiler or the static tool) believes that your enum is not the same size and/or signedness as an int.
My Green Hills compiler has an option --short-enum (Use Smallest Type Possible for Enum) that will select a char type for your example above. Does your compiler have such an option? Is it enabled? Does the compiler default enums to a "non-standard" value?
In my experience, by default static tools follow the language spec pretty well by default, meaning that it should expect an enum to be int-sized. (See this link for reference: What is the size of an enum in C?). Since most static tools snoop your compiler command-line usage, your compile-time options may be convincing the static analyzer that your enums are smaller than ints.
I suggest reviewing your compiler and static analyzer documentation thoroughly to resolve the conflict. Keep a close eye on your build process, too (compile-time options, defaults, etc).
回答3:
It is likely as a result of the declaration of my_color
enum Color my_color;
Try removing 'enum' from this:
Color my_color;
The static analyser probably reckons that you are declaring a separate enum, thus the 10.1 violation. Since its then a different type, the MISRA rule forbids assigning one type to another.
来源:https://stackoverflow.com/questions/10589684/misra-violation-rule-10-1-and-enums