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

1

9

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?

Mcclanahan answered 24/1, 2019 at 13:52 Comment(1)
For this level of detail you really need to just read the source code. This is common style of documentation for GNU-software.Impellent
M
9

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.

Mossgrown answered 24/1, 2019 at 14:11 Comment(5)
Thanks for the link. My question is: How is the dependency on the API, and where is that documented?Mcclanahan
@Mcclanahan The ABI is the low level system setup and gcc doesn't necessarily have anything to say about it. Obviously, it is system-specific. Here's one example for x86: github.com/hjl-tools/x86-psABI/wiki/X86-psABIMossgrown
Thanks for the link. 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?Mcclanahan
@Mcclanahan I don't know, I'm not the right person to ask regarding the internals of the gcc compiler.Mossgrown
Re 'how is the dependency on the ABI'. I am not trying to be sarcastic here, but it is defined as part of the ABI because this is the sort of information that is defined by an ABI. How the the 'c' calling convention is implemenetd is part of the ABI for each processor, whether the parameters go on the stack or whether they can be stored in registers. Similarly how enums are represented is also part of the ABI for each processorSeasonal

© 2022 - 2024 — McMap. All rights reserved.