代码之家  ›  专栏  ›  技术社区  ›  Dacav

用C++ 11 Enm类保存ABI兼容性

  •  2
  • Dacav  · 技术社区  · 6 年前

    这个问题和 Does adding enumerators into enum break ABI? 但是 enum class 由C++ 11介绍。

    据我所知 this page 我只需定义一个稳定的ABI 潜在类型 对于我的列举:

    enum class Foo : uint32_t
    {
        x, y, z
    }
    

    我会说这很好,比如

    enum class Foo : uint8_t { x = 257 }
    

    不会编译。这意味着编译器不再悄悄地改变枚举的大小,因此我不会破坏二进制兼容性。

    我说的对吗?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Shafik Yaghmour    6 年前

    我相信 the accepted answer to the referenced question 回答关于ABI兼容性的大多数问题。我可以在这里重复一遍,但在那里我看不到什么价值。

    针对C++ 11域范围枚举的特定问题,请举例说明:

    enum class Foo : uint8_t { x = 257 }
    

    是格式错误的,因为它需要收缩转换,因此需要实现提供诊断,但如果实现仅使其发出警告,则它可能会编译。正如您所要求的,编译器不会悄悄地改变底层类型的大小。

    我们可以从C++标准草案中看出这一点。 dcl.enump5 :

    每个枚举定义的类型不同于所有其他类型。每个枚举也有一个基础类型。可以使用枚举基显式指定基础类型。对于作用域枚举类型,如果未显式指定,则基础类型为int。在这两种情况下,底层类型都是固定的。在枚举说明符的右大括号之后,每个枚举器都有其枚举类型。 如果基础类型是固定的,则右大括号前面的每个枚举器的类型是基础类型,枚举器定义中的常量表达式应是基础类型的转换常量表达式。 . 如果基础类型不是固定的,则在右大括号之前的每个枚举器的类型确定如下:…

    转换常量表达式 禁止变窄,从 expr.constp5 :

    类型t的转换常量表达式是隐式转换为类型t的表达式,其中转换的表达式是常量表达式,隐式转换序列仅包含

    • 积分转换 缩小转换除外 ,

    ……

        2
  •  0
  •   Dacav    6 年前

    这里是OP。

    我发现了,我认为这是相关的,提到C++ 11有这么好。 std::underlying_type .

    我想它可以和 is_same static assertions ,以防止ABI因枚举而发生意外更改。

    我认为(但我没有尝试)如果使用某个库,并且预先存在的枚举没有指定底层类型,那么这就特别相关。