39

Is the enum type signed or unsigned? Does the signedness of enums differ between: C/C99/ANSI C/C++/C++x/GNU C/ GNU C99?

Thanks

a2800276
  • 3,272
  • 22
  • 33
osgx
  • 90,338
  • 53
  • 357
  • 513

2 Answers2

32

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.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • 2
    What signedness is actually used by gcc? – osgx Apr 05 '10 at 15:46
  • 1
    @osgx: I would guess that it would depend on the number of enumerators and the range of their values. I really don't know. – James McNellis Apr 05 '10 at 16:02
  • 4
    The C standard also specifies that each *enumeration constant* has type `int`. Howeve, the term “enumeration constant” refers to the value constants declared inside the `enum { }` block. A variable with an `enum` type may have any integer type in C, e.g. it might be a shorter type than `int` if one can represent all the values. (GCC, for example, has an option `-fshort-enums` for doing precisely this.) – Arkku Apr 05 '10 at 16:14
  • The term "enumerator" is commonly understood as the enumeration constant, and AFAIK inside the `enum{}` they never have a type smaller than `int` because the compiler doesn't know yet what values will follow. – MSalters Apr 06 '10 at 15:39
  • @MSalters @Arkku: That's true; in C, enumeration constants are always of type `int`. In C++, they are of the same type as their initializer, so they could be of any integral type. – James McNellis Apr 06 '10 at 16:03
  • 14
    @osgx GCC decides at compile time what signedness to apply to an `enum`. I have an enumerator with values from zero upwards and within a function check that the values of that enumerator are never less than zero (it is used as an array index). GCC gives me an warning `avServerApi.c:23: warning: comparison of unsigned expression < 0 is always false` If I put a dummy `-1` in the `enum` then the warning goes away as the enumerator is then signed. – Matt Clarkson Jul 28 '11 at 17:39
0

This is an old question... but I've just found out this:

typedef unsigned ENUMNAME;  // this makes it unsigned in MSVC C 2015
typedef enum {v0, v1, v2, v3} ENUMNAME;

You can use it as an 2-bit unsigned index, for example:

typedef struct {
  ENUMNAME i:2;
} STRUCTNAME;

Tried it in GCC ARM - doesn't work.
Also, WinDbg shows STRUCTNAME.i as a number, not as v0-v3.

aleksazr
  • 89
  • 7