Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Index into an array of values of some `enum` type in C

Tags:

c

enums

The C11 spec on enums1, states that the enumerator constants must have type int (1440-1441):

1440 The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.

1441 The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted.107)

However, it indicates that the backing type of the enum can be either a signed int, and unsigned int, or a char, so long as it fits the range of constants in the enum (1447-1448):

1447 Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type.

1448 The choice of type is implementation-defined,108) but shall be capable of representing the values of all the members of the enumeration.

This seems to indicate that only the compiler can know the width of an enum type, which is fine until you consider an array of enum types as part of a dynamically linked library.

Say you had a function:

enum my_enum return_fifth(enum my_enum[] lst) {
    return lst[5];
}

This would be fine when linked to statically, because the compiler knows the size of a my_enum, but any other C code linking to it may not.

So, how is it possible for one C library to dynamically link to another C library, and know how the compiler decided to implement the enums? (Or do most modern compilers just stick with int/uint and forgo using chars altogether?

1Okay, I know this website is not quite the C11 standard, where as this one is a bit closer: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

like image 372
Leif Andersen Avatar asked Nov 07 '22 01:11

Leif Andersen


1 Answers

C standard doesn't says anything about dynamical library or even static library, these concepts doesn't exist in standard. This is in the implemented behavior domain.

But as you said nothing prevent a compiler to use different type for an enumeration, this mean the one compiler can use a type and another use a different type.

This would be fine when linked to statically

In fact no, let say that A is a compiler that used char and B is a compiler that used int, and let say these types are not the same size. You compile a static library with the A compiler, and you statically link this library to a program compiled by B. This is static and still, B can't know that A doesn't use the B type for the enum.

So, how is it possible for one C library to dynamically link to another C library

Well, as I said this is not possible for static library, for the same reason, this is not possible for dynamic library.

Or do most modern compilers just stick with int/uint and forgo using chars altogether?

Big compiler generally talk between them to use the same rules on the same environment, yes. But nothing in C guaranty this behavior. (On the compatibility problem: a lot of people use "The C ABI", despite the fact it doesn't exist in the standard.)

So the best advice is to compile your dynamic library with the same compiler and option that compile your main program, also check the documentation of your compiler is a big plus.

like image 147
Stargateur Avatar answered Nov 15 '22 05:11

Stargateur