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