Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to specify the bit width of an enum in C++11?

Tags:

I'm exchanging packets with an embedded device and I'd really like to be able to use enums in the sub-byte parts of the packet definitions too. But I can't guess a syntax that might work and I suspect it's not possible, since I can't work out how to declare a partial-byte subtype in C++:

enum class communication_path_t : uint8_t  {      Ethernet = 0, Wifi = 1 };  typedef struct {     communication_path_t pathByte;  // works, uses one byte     // ...      // single byte split three ways     uint8_t retryCount : 3;     communication_path_t path : 3;  // compile error     uint8_t deviceType : 2; } packet_t; 

That doesn't compile, because you can't fit an 8 bit enum into a 3 bit field. Edited in the exact error:

<anonymous struct>::path’ is too small to hold all values    of ‘enum class MyNamespace::communication_path_t’ [-Werror] 

What I'd like to do is something like this:

enum class communication_path_t : uint8_t : 3 { ... 

or

typedef uint8_t:3 three_bit_int_t; enum class communication_path_t : three_bit_int_t { ... 

Neither of those compile, and I'm having trouble finding documentation that refers to both bit fields and enums, making me suspect there is none. Before I spend hours looking, is what I'm trying to do even possible?


Edit: upgrading to g++-4.9 does not fix the problem. It's remarkably painless, just:

sudo apt-get install g++-4.9 g++-4.9 --version  g++-4.9 (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2 GCC 4.9.2 released [2014-10-30] 

Then change my build chain to use "g++-4.9" instead of "g++". Unfortunately I get the same error:

g++-4.9 -Dlinux -std=c++11 -pthread (...) ../common/LogPacketBreakdown.cpp In file included from ../common/LogPacketBreakdown.cpp:12:0: ../common/PacketInfo.h:104:50: error: ‘Digiflex::<anonymous     struct>::communicationPath’ is too small to hold all values of      ‘enum class Digiflex::communication_path_t’ [-Werror]     communication_path_t communicationPath : 3; 

Looks as though I need 5.0 and that's not in the Ubuntu experimental tools list so I'd need to build from source. I think I'll just live with the workaround for now. Thanks all for your help.

like image 367
Code Abominator Avatar asked Feb 09 '15 02:02

Code Abominator


People also ask

How many bits is an enum in C?

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.

Why is enum 4 bytes?

The size is four bytes because the enum is stored as an int . With only 12 values, you really only need 4 bits, but 32 bit machines process 32 bit quantities more efficiently than smaller quantities.


1 Answers

The code you posted should be accepted by the most recent compilers. You can see this bug report where the fix should have occurred: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51242

In today's gcc, a warning should still be emitted. In clang, you should see nothing.

like image 73
Bill Lynch Avatar answered Oct 07 '22 01:10

Bill Lynch