Are C++ Enums Signed or Unsigned

Are C++ enums signed or unsigned?

You shouldn't rely on any specific representation. Read the following link. Also, the standard says that it is implementation-defined which integral type is used as the underlying type for an enum, except that it shall not be larger than int, unless some value cannot fit into int or an unsigned int.

In short: you cannot rely on an enum being either signed or unsigned.

Is there a way to make an enum unsigned in the C90 standard? (MISRA-C 2004 compliant)

There is no standard C way to control the type chosen for an enum. You can do it in implementation specific ways sometimes, like by adding a value to the enumeration that forces the type to be unsigned:

enum {
x1,
x2,
x3,
giant_one_for_forcing_unsigned = 0x80000000;
};

But that's not even standard C, either (since the value provided won't fit in an int). Unfortunately, you're pretty much out of luck. Here's the relevant bit from the standard:

6.7.2.2 Enumeration specifiers, paragraph 4

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration. The enumerated type is incomplete until immediately after the } that terminates the list of enumerator declarations, and complete thereafter.

You might be better off using #define rather than enum to make your constants:

#define x1 0U
#define x2 1U
#define x3 2U

uint8_t x = x2;

Signedness of enum in C/C99/C++/C++x/GNU C/GNU C99

An enum is guaranteed to be represented by an integer, but the actual type (and its signedness) is implementation-dependent.

You can force an enumeration to be represented by a signed type by giving one of the enumerators a negative value:

enum SignedEnum { a = -1 };

In C++0x, the underlying type of an enumeration can be explicitly specified:

enum ShortEnum : short { a };

(C++0x also adds support for scoped enumerations)

For completeness, I'll add that in The C Programming Language, 2nd ed., enumerators are specified as having type int (p. 215). K&R is not the C standard, so that's not normative for ISO C compilers, but it does predate the ISO C standard, so it's at least interesting from a historical standpoint.

Casting enum definition to unsigned int

Unfortunately ISO C standard (c99 6.4.4.3) states that the enumeration constants are of type int. If you compile the above with e.g. gcc -W -std=c89 -pedantic, it will issue a warning ISO C restricts enumerator values to range of ‘int’ [-pedantic]. Some embedded compilers may not accept the code at all.

If your compiler is of the pickier variety, you can workaround the issue by using

typedef enum hardware_register_e
{
REGISTER_STATUS_BIT = -2147483648 /* 1<<31, for 32-bit two's complement integers */
} hardware_register_t;

but it works correctly only if int is 32-bit two's complement type on your architecture. It is on all 32-bit and 64-bit architectures I have ever used or heard of.

Edited to add: ARM7 uses 32-bit two's complement int type, so the above should work fine. I only recommend you keep the comment explaining that the actual value is 1<<31. You never know if somebody ports the code, or uses another compiler. If the new compiler issues a warning, the comment on the same line should make it trivial to fix. Personally, I'd wrap the code in a conditional, perhaps

typedef enum hardware_register_e
{
#ifdef __ICCARM__
REGISTER_STATUS_BIT = -2147483648 /* 1<<31, for 32-bit two's complement integers */
#else
REGISTER_STATUS_BIT = 1 << 31
#endif
} hardware_register_t;

Is there a way to make `enum` type to be unsigned?

You might try:

enum EEE {
X1 = 1,
XN = -1ULL
};

Without the U, the integer literal is signed.

(This of course assumes your implementation supports long long; I assume it does since the original question uses LL; otherwise, you can use UL for a long).

Why does 'typeof enum constant' generate a warning when compared to a variable of enum type?

Quoting directly from C11, chapter §6.7.2.2, Enumeration specifiers,

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined.

So, the type of the enum variable is not defined by standard. It can be any of the above.

OTOH, FOO being an enumeration constant, typeof(FOO) will give you int, as the standard mandates

An identifier declared as an enumeration constant has type int.

which is being used as the type for f2.

Now, if enum is unsigned int on your implementation, so is f1 and, f2 is int.

Next, you get the warning.

How can I fix this problem?

Well, if you change the type of f2 to typeof(Baz), which gives the type of the enum, then both the types of f1 and f2 will be same. Compiler will be happy.

SEE LIVE HERE



Related Topics



Leave a reply



Submit