Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c enum with 32 bit values

Tags:

c

gcc

i need some unsigned 32bit enum values for my software, therefore i implemented this (simple) enum:

enum{
   val1    = 0xFFFFFFFFu,
   val2    = 0xFFFFFFFEu,
   val3    = 0xFFFFFFF0
};

The problem: Everytime i run the compiler, Eclipse aborts compiling and marks the enum with the following error:
enter image description here
In my oppinion, a 32 int value should not be a problem for enums, but obviously it seems to be. I would be grateful about some input :)

[Update 1:] I will try to find the problem in the compiler settings, i will keep you up to date

like image 874
Thomas Richter Avatar asked Jan 31 '17 10:01

Thomas Richter


People also ask

Are enums 32 bit?

On an 8-bit processor, enums can be 16-bits wide. On a 32-bit processor they can be 32-bits wide or more or less. The GCC C compiler will allocate enough memory for an enum to hold any of the values that you have declared. So, if your code only uses values below 256, your enum should be 8 bits wide.

Can enum be 64 bit?

For C++ and relaxed C89/C99/C11, the compiler allows enumeration constants up to the largest integral type (64 bits).

What is the size of enum variable in C?

In C language, an enum is guaranteed to be of size of an int . There is a compile time option ( -fshort-enums ) to make it as short (This is mainly useful in case the values are not more than 64K). There is no compile time option to increase its size to 64 bit.


2 Answers

An enumeration constant (val1 in your example) is required to be of type int by the C standard. This is a signed type and on a 32 bit system, the value FFFFFFFF will not fit inside it. This value will therefore get converted to a signed integer in some implementation-defined (compiler-specific) manner. If this can't be done, you'll get an implementation-defined signal.

Writing code which relies on this is bad, since it is non-portable and unpredictable. There is no compiler setting that can fix this, because this is by language design.

I believe the gcc flag -pedantic/-pedantic-errors could be removed in order to get rid of the warning, but that's a bad idea, as you will no longer follow standard C. gcc in its default, non-standard "skunk mode" -std=gnu90 or -std=gnu11 will compile the code, as will any -std=cxx without -pedantic-errors.

This is why enums are unsuitable for any form of bit masks or bit-wise operations.

The best solution is to get rid of the enum and use either #define or const uint32_t, whichever is most convenient for your specific scenario.

like image 109
Lundin Avatar answered Oct 27 '22 16:10

Lundin


Did you try this?:

enum {
   val1    = (int)0xFFFFFFFFu,
   val2    = (int)0xFFFFFFFEu,
   val3    = (int)0xFFFFFFF0
};

Edit: I just installed gcc on cygwin and tried this out.

test-enum.c is the original version, test-enum-int.c the one with explicit casting:

$ cc -std=c11 -pedantic-errors -c test-enum.c
test-enum.c:2:8: error: ISO C restricts enumerator values to range of 'int' [-Wpedantic]
   val1 = 0xFFFFFFFFu,
          ^
test-enum.c:3:8: error: ISO C restricts enumerator values to range of 'int' [-Wpedantic]
   val2 = 0xFFFFFFFEu,
          ^
test-enum.c:4:8: error: ISO C restricts enumerator values to range of 'int' [-Wpedantic]
   val3 = 0xFFFFFFF0u
          ^

$ cc -std=c11 -pedantic-errors -c test-enum-int.c

(no complains)

$ cc --version
cc (GCC) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
like image 45
Scheff's Cat Avatar answered Oct 27 '22 17:10

Scheff's Cat