C++ 向枚举中添加枚举数是否会破坏ABI?

C++ 向枚举中添加枚举数是否会破坏ABI?,c++,enums,abi,C++,Enums,Abi,特别是,我在库接口中获得了以下代码: typedef enum { state1, state2, state3, state4, state5, state_error = -1, } State; 我严格禁止打破ABI。但是,我想添加state6和state7。它会打破ABI吗 我找到了一些线索,但我有点怀疑这是否是我的情况 你可以 将新枚举数附加到现有枚举 Exeption:如果这导致编译器为枚举选择一个更大的底层类型,则会使更改二进制

特别是,我在库接口中获得了以下代码:

typedef enum
{
    state1,
    state2,
    state3,
    state4,
    state5,
    state_error = -1,
} State;
我严格禁止打破ABI。但是,我想添加state6和state7。它会打破ABI吗

我找到了一些线索,但我有点怀疑这是否是我的情况

你可以

  • 将新枚举数附加到现有枚举

Exeption:如果这导致编译器为枚举选择一个更大的底层类型,则会使更改二进制不兼容。不幸的是,编译器在选择底层类型方面有一定的余地,因此从API设计的角度来看,建议添加一个Max。。。。带有显式大值(=255,=1引号实际上就是您的情况。只需在末尾添加新的枚举值(但在
state_error
之前,因为它具有不同的值)它应该是二进制兼容的,除非如您提供的引用中所述,编译器选择使用不同大小的类型,这在如此小的枚举中似乎不太可能


最好的方法是尝试并检查:在更改前后执行一个简单的
sizeof(State)
就足够了(尽管您可能还想检查值是否仍然相同)。

查看值最高的枚举器id:
state3
是2

这意味着,即使编译器应该选择
char
作为底层类型,您也可以轻松地在那里添加100多个枚举器ID,而不会损害二进制兼容性


但是,这假设用户提供迭代器的值,而不是读取迭代器的值。

您的问题就是一个很好的例子,说明了为什么长期维护ABI兼容性是一项困难的任务。这里的核心问题是,兼容性不仅取决于给定的类型,还取决于它在函数/方法p中的使用方式旋转类型或复杂类型(例如结构、联合等)

< P>(1)如果枚举在任何地方用作库的输出(例如返回值或函数填充由调用方A.K.A输出参数提供的地址),则该更改将中断ABI。考虑枚举为“应用程序从未看到其他值,然后列出”的契约。。添加新的枚举成员将破坏此约定,因为旧应用程序现在可以看到从未计算过的值


(2) 如果枚举严格用作库的输入(例如,作为函数的一个参数,它只是改变函数/库的行为),然后它保持兼容性:您以一种不会伤害客户的方式更改了合同,即呼叫应用程序。旧应用程序永远不会使用新值,并将获得旧行为,新应用程序只会获得更多选项。

state3
有三种不同的代码?在保留现有枚举的同时添加新枚举应只要基础类型的大小不因添加而改变,dn就不会破坏ABI兼容性。这是您引用的材料所说的。换句话说,可能会削弱库的要求而不会造成伤害,但不会削弱其保证。小心那些依赖参数验证来拒绝s中无效输入的人但具体的方式是这样的。。。