特别是,我在库接口中获得了以下代码:
typedef enum
{
state1,
state2,
state3,
state4,
state5,
state_error = -1,
} State;
Run Code Online (Sandbox Code Playgroud)
我严格禁止打破ABI.但是,我想添加state6和state7.它会破坏ABI吗?
您可以...
- 将新枚举器附加到现有枚举.
执行:如果这导致编译器为枚举选择更大的底层类型,则会使更改与二进制不兼容.遗憾的是,编译器有一些余地可以选择底层类型,因此从API设计的角度来看,建议添加一个带有显式大值(= 255,= 1 << 15等)的Max ....枚举器来创建一个数值枚举器值的间隔,保证适合所选的基础类型,无论可能是什么.
mit*_*ity 13
您的问题是一个很好的例子,为什么长期维持ABI兼容性是一项艰巨的任务.这里问题的核心是兼容性不仅取决于给定的类型,还取决于它在函数/方法原型或复杂类型(例如结构,联合等)中的使用方式.
(1)如果枚举在任何地方用作库的输出(例如返回值或函数填充调用者提供的某些地址,也就是输出参数),则更改将破坏ABI.将枚举视为合同,称"应用程序永远不会看到除列出的值之外的值".添加新的枚举成员会破坏此合同,因为旧的应用程序现在可以看到他们从未计算过的值.
(2)如果枚举严格用作输入到库(例如,作为一个刚刚行为函数/库的变化函数的参数),然后将其保持兼容性:您方式,也永远不能改变合同伤害了客户,即调用应用程序.旧应用程序永远不会使用新值,并且会获得旧行为,新应用程序只会获得更多选项.