Reputation: 69
How can I define the type of an enum to be uint8 instead of int?
typedef enum
{
R_DIRECTION_LEFT = 1,
R_DIRECTION_RIGHT = 2,
R_DIRECTION_TOP = 4,
R_DIRECTION_BOTTOM = 8
} R_Direction;
Upvotes: 4
Views: 5955
Reputation: 133189
The C standard doesn't support that but the clang compiler does:
typedef enum: uint8_t
{
R_DIRECTION_LEFT = 1,
R_DIRECTION_RIGHT = 2,
R_DIRECTION_TOP = 4,
R_DIRECTION_BOTTOM = 8
} R_Direction;
Compare: https://www.ideone.com/EQj170
to: https://www.ideone.com/7WitM8
See also: Clang Language Extensions
Upvotes: 0
Reputation: 215090
As already mentioned in other answers, there is no standard way to solve this, since the standard says that enumeration constants are int
. The types of enumeration constants and variables is a known major flaw in the language.
The solution is simply to cast the enumeration constant into uint8_t
whenever using it. When the size and signedness of a value matters, it might be best to avoid enums entirely. #define
or const
can be used to create type-safe alternatives.
Upvotes: 0
Reputation: 8537
If you use GCC, you can use __attribute__ ((packed))
to reduce the size of variables of this type. From here:
This [
packed
] attribute, attached to an enum, struct, or union type definition, specified that the minimum required memory be used to represent the type.
Since your enum only has values in range from 0 to 255, it will fit in a single byte when this attribute is applied.
There's a related compiler option:
Specifying the
-fshort-enums
flag on the [command] line is equivalent to specifying the packed attribute on allenum
definitions.
Upvotes: 1
Reputation: 21362
The identifiers in an enum
list have type int
, as per §6.7.2.2 3 of the C11 Standard:
The identifiers in an enumerator list are declared as constants that have type
int
and may appear wherever such are permitted.
But, enumerations constitute distinct types §6.2.5 16:
Each distinct enumeration constitutes a different enumerated type.
Of the enumerated type itself, the Standard says in §6.7.2.2 4 only that:
Each enumerated type shall be compatible with
char
, asigned
integer type, or anunsigned
integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration.
Further, in a footnote it is pointed out that:
An implementation may delay the choice of which integer type until all enumeration constants have been seen.
So the type of an enumeration is distinct, and this type must be compatible with one of char
, a signed
integer type, or an unsigned
integer type. Which of these will be used is implementation-defined, and may vary from case to case on the same implementation.
Upvotes: 2
Reputation: 1
How can I define the type of an enum to be uint8 instead of int?
You can't. Per 6.7.2.2 Enumeration specifiers, paragraph 2, of the C standard:
The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an
int
.
Upvotes: 0
Reputation: 30936
No you can't.
From standard §6.4.4.3 C11 standard N1570
An identifier declared as an enumeration constant has type int.
Upvotes: 4