|
After reading the MISRA-C:2004 guideline and earlier posts to this
forum, I have concluded the following about enum:s:
* An enum object is in standard C "int", and hence has the underlying
type "int".
* An enum constant has the underlying type corresponding to the
magnitude, as specified by the table in 6.10.4
However, this leaves one open question: What is the sign of an enum
constant?
The background is that in embedded devices, peripheral units are often
memory mapped and described using a struct, for example:
Code: /* Typical peripheral usage */
enum my_enum
{
FIELD1 = 0x01U,
FIELD2 = 0x02U,
};
typedef unsigned short my_uint16_t;
struct my_struct
{
my_uint16_t x;
} s;
void test1(void);
void test2(enum my_enum v);
void do_something(void);
void test1(void)
{
s.x = (FIELD1 | FIELD2);
}
void test2(enum my_enum v)
{
if (v == FIELD1)
{
do_something();
}
}
/* End of example */
Back to the question: do enum constans get the same signedness as the
initializer expression. In other words, can enum constants be
unsigned?
Alternative 1: Always signed
If we assume that the underlying type is signed, then the assignment
in "test1" will break rule 10.1, as the expression to the right has
the underlying type "signed char".
If this is the case, enum can't be used to describe bits in bitmask in
a MISRA-C-compliant application. This is a big drawback and would make
MISRA-C much less useful in real-world applications, as it would force
peripheral units to be described using preprocessor macros.
Alternative 2: Get type from the initializer expression
On the other hand, if the enum constants inherit the underlying type
from the initializer expression, it could be something like "unsigned
char". In which case, any operation involving an enum object (int) and
enum constants (e.g. unsigned char) appears to break rule 10.1, as
there will be an implicit conversion from "unsigned char" to "signed
int". For example, see the comparison in "test2".
Also, if this enum constant inherit the signedness from initializer
expression, what happens when the expression is left out, should it
inherit the type from the previous enum constant?
Code: enum my_other_enum
{
AnUnsignedConstant = 0x10U,
IsThisSignedOrUnsigned
}
To conclude, I would like to know if enum constants should inherit the
signedness from the initializer expressions and, if so, should the
tools issue a MISRA-C error for expressions involving enum objects and
enum constants?
By the way, I work for a company providing a MISRA-C checker. In order
to make the tools as good as possible, I would like to get a straight
answer to the questions I ask in relation to rule 10.1 -- whether or
not the example code breaks other MISRA-C rules is irrelevant.
|