使用const全局变量而不是枚举确保ABI兼容性吗?

时间:2016-03-12 21:47:46

标签: c 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;

2 个答案:

答案 0 :(得分:4)

你是对的。如果您计划扩展枚举变量,则可能会使您的库的未来版本不兼容 如果你看一些最相关的sw(即MS或linux标题),你会发现所采用的解决方案主要是两个:

  1. 使用定义
  2. 仍然使用枚举,但为每个条目指定一个值
  3. 后者使枚举与定义完全相同,但保留了枚举的属性 在你的情况下,它可能是:

    // 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
    }
    

    使用常量全局变量可能会遇到一些问题,甚至可以进行优化并替换为常量。

答案 1 :(得分:0)

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

更改枚举仍然需要重新编译/链接库等(没有绕过它),

为确保枚举中的每个标签都具有特定值,枚举可以类似于:

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

匿名枚举中的结果,其中每个标签都是可见的并且具有适当的值。