Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is the default enum size (short or no-short) determined by the configure options of gcc?

Tags:

c

enums

gcc

abi

I tried some gcc compilers to see if the default enum size is short (at least one byte, as forced with -fshort-enums) or no-short (at least 4 bytes, as forced with -fno-short-enums):

user@host:~$ echo '_Static_assert(4 == sizeof(enum{E}), "enum size is not 4");' | x86_64-linux-gnu-gcc -fsyntax-only -xc - && echo "OK, enum size is 4 on x86_64-linux-gnu"
OK, enum size is 4 on x86_64-linux-gnu

user@host:~$ echo '_Static_assert(4 == sizeof(enum{E}), "enum size is not 4");' | arm-linux-gnueabihf-gcc -fsyntax-only -xc - && echo "OK, enum size is 4 on arm-linux-gnueabihf"
OK, enum size is 4 on arm-linux-gnueabihf

user@host:~$ echo '_Static_assert(4 == sizeof(enum{E}), "enum size is not 4");' | /opt/Atollic_TrueSTUDIO_for_STM32_x86_64_9.1.0/ARMTools/bin/arm-atollic-eabi-gcc -fsyntax-only -xc -
<stdin>:1:1: error: static assertion failed: "enum size is not 4"

user@host:~$ echo '_Static_assert(4 == sizeof(enum{E}), "enum size is not 4");' | /opt/Atollic_TrueSTUDIO_for_STM32_x86_64_9.1.0/ARMTools/bin/arm-atollic-eabi-gcc -fno-short-enums -fsyntax-only -xc - && echo "OK, enum size is 4 on arm-atollic-eabi with -fno-short-enums"
OK, enum size is 4 on arm-atollic-eabi with -fno-short-enums

As you can see, short is the default on embedded targets, while no-short is the default on hosted platforms. This makes sense to improve binary compatibility on hosted platforms. Now:

What is the rule that tells me if enums will be short depending on the configure options when building gcc and where is it documented?

Edit:

As pointed out in Lundin's answer, the gcc manual states that

On some targets, -fshort-enums is the default; this is determined by the ABI.

My question is: How is the dependency on the ABI, and where is it documented? Do the gcc sources contain a kind of database that map architectures (e.g. arm-linux-gnueabihf) to ABIs and a kind of database that specifies all the options (e.g. short enums or no-short enums) for each ABI? Or is it all hard-coded magic scattered throughout the whole source tree?

like image 535
not-a-user Avatar asked Jan 24 '19 13:01

not-a-user


People also ask

How do you specify the size of an enum?

The C standard specifies that enums are integers, but it does not specify the size. Once again, that is up to the people who write the compiler. 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.

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.


1 Answers

In the gcc manual, look for implementation-defined behavior. Chapter 4.9.

The integer type compatible with each enumerated type (C90 6.5.2.2, C99 and C11 6.7.2.2).

Normally, the type is unsigned int if there are no negative values in the enumeration, otherwise int. If -fshort-enums is specified, then if there are negative values it is the first of signed char, short and int that can represent all the values, otherwise it is the first of unsigned char, unsigned short and unsigned int that can represent all the values.

On some targets, -fshort-enums is the default; this is determined by the ABI.

The italic part is cited from the C standard's implementation-defined behavior. As you can see, the type is adaptive depending on which enumeration constants there are. It need not have the same size consistently through your program, for different enum types.

Optimization settings might matter, since 4 bytes enum might be faster than 1 byte enum on some machines.

like image 135
Lundin Avatar answered Nov 15 '22 19:11

Lundin