Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用const全局变量而不是enum是否可以确保ABI兼容性?_C_Abi - Fatal编程技术网

使用const全局变量而不是enum是否可以确保ABI兼容性?

使用const全局变量而不是enum是否可以确保ABI兼容性?,c,abi,C,Abi,在我的一个C库项目中,我有一个枚举,它列出了库处理的所有可能的数据类型: // lib.h enum types { VOID, INT, FLOAT, CONST_INT, CONST_FLOAT } 代码将被编译到一个共享库中。在库的未来版本中,我将被要求在枚举中插入新条目并对现有条目重新排序。AFAIK这会破坏ABI兼容性,因为枚举不会转换为一组符号,这些符号最终会出现在库中,而是会导致编译器分配给每个条目的任何整数都被硬编码。是这样吗 如果是这样

在我的一个C库项目中,我有一个枚举,它列出了库处理的所有可能的数据类型:

// lib.h
enum types {
    VOID,
    INT,
    FLOAT,
    CONST_INT,
    CONST_FLOAT
}
代码将被编译到一个共享库中。在库的未来版本中,我将被要求在枚举中插入新条目并对现有条目重新排序。AFAIK这会破坏ABI兼容性,因为枚举不会转换为一组符号,这些符号最终会出现在库中,而是会导致编译器分配给每个条目的任何整数都被硬编码。是这样吗

如果是这样,是否最好改用常量全局变量,使其出现在符号表中,从而可以更改顺序和分配给每个变量的值

// lib.c
const int VOID = 1;
const int INT = 2;
const int FLOAT = 3;
const int CONST_INT = 4;
const int CONST_FLOAT = 5;

// lib.h
extern const int VOID;
extern const int INT;
extern const int FLOAT;
extern const int CONST_INT;
extern const int CONST_FLOAT;

你说得对。如果计划展开枚举变量,则可能会使库的未来版本不兼容。 如果您查看一些最相关的软件,例如MS或linux头文件,您会发现采用的解决方案主要有两种:

使用定义 仍然使用enum,但为每个条目分配一个值 后者使enum的使用与defines相当,但保留了enum的属性。 在您的情况下,可能是:

// lib.h
enum types {
    VOID = 0,
    INT = 1,
    FLOAT = 10,
    CONST_INT = 12,
    CONST_FLOAT = 13
}
然后,将来您将添加其他代码时:

// lib.h
enum types {
    VOID = 0,
    INT = 1,
    CUSTOM1 = 3,
    FLOAT = 10,
    CUSTOM2 = 11,
    CONST_INT = 12,
    CONST_FLOAT = 13,
    CUSTOM4 = 20
}

常量全局变量的使用可能会有一些问题,甚至需要进行优化并用常量替换。

最好的方法是将枚举放在该库的头文件中

更改枚举仍将需要重新编译/链接库等

为确保枚举中的每个标签都具有特定值,枚举的写入方式类似于:

enum 
{
    label1 = 0,
    label2 = 1,
    label3 = 20,
    label4 = 5
};

结果将显示在匿名枚举中,其中每个标签都是可见的并具有相应的值。

请注意,向枚举添加条目会更改类型,并可能会生成用于存储枚举变量的更大整数类型,这就是为什么您偶尔会看到大的/负的保留填充条目以备将来验证。诚然,在实践中,这主要是8位ABI上的一个问题,尤其是对于连续枚举。@doynax解决方案是使用int作为任何变量的类型,该变量将包含这些枚举数中的一个。所有枚举数都是int,而不考虑enum@M.M:这确实是最常见的解决方法。但是,在破译这些值时,调试器没有提供任何帮助,这有点烦人。