枚举1 上的C11规范声明枚举器常量必须具有int类型(1440-1441):
1440定义枚举常量值的表达式应为整数常量表达式,其值可表示为int.
1441枚举器列表中的标识符声明为具有int类型的常量,并且可以出现在允许的位置.107)
但是,它表明枚举的支持类型可以是signed int,unsigned int或char,只要它符合枚举(1447-1448)中的常量范围:
1447每个枚举类型应与char,有符号整数类型或无符号整数类型兼容.
1448类型的选择是实现定义的,108)但应能够表示枚举的所有成员的值.
这似乎表明只有编译器才能知道枚举类型的宽度,这一点很好,直到您将枚举类型数组视为动态链接库的一部分.
说你有一个功能:
enum my_enum return_fifth(enum my_enum[] lst) {
return lst[5];
}
Run Code Online (Sandbox Code Playgroud)
这在链接到静态时会很好,因为编译器知道a的大小my_enum,但链接到它的任何其他C代码可能不知道.
那么,一个C库如何动态链接到另一个C库,并知道编译器如何决定实现枚举?(或者大多数现代编译器只是坚持int/ uint并且char完全放弃使用s?
1好的,我知道这个网站不是C11的标准,因为这个标准更接近:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
C 标准没有提到任何关于动态库甚至静态库的内容,这些概念在标准中不存在。这是在已实现的行为域中。
但正如您所说,没有什么可以阻止编译器使用不同类型进行枚举,这意味着一个编译器可以使用一种类型,而另一个编译器可以使用不同的类型。
当静态链接时这会很好
事实上不是,假设 A 是使用的编译器char,B 是使用的编译器int,并且假设这些类型的大小不同。您使用 A 编译器编译一个静态库,然后将该库静态链接到 B 编译的程序。这是静态的,B 仍然无法知道 A 没有使用 B 类型作为枚举。
那么,一个 C 库如何动态链接到另一个 C 库
好吧,正如我所说,这对于静态库来说是不可能的,出于同样的原因,这对于动态库来说也是不可能的。
或者大多数现代编译器只是坚持使用 int/uint 而完全放弃使用字符?
大型编译器通常会在同一环境下使用相同的规则,是的。但 C 语言中没有任何内容可以保证这种行为。(关于兼容性问题:很多人使用“The C ABI”,尽管事实上它并不存在于标准中。)
因此,最好的建议是使用与编译主程序相同的编译器和选项来编译动态库,同时检查编译器的文档是一个很大的优势。