【问题标题】:Does changing the order of class private data members breaks ABI更改类私有数据成员的顺序是否会破坏 ABI
【发布时间】:2011-02-26 00:34:05
【问题描述】:

我有一个类,其中包含许多私有数据成员(其中一些是静态的),由虚拟和非虚拟成员函数访问。没有内联函数,也没有友元类。

class A
{
    int number;
    string str;
    static const int static_const_number;
    bool b;
public:
    A();
    virtual ~A();
public:
    // got virtual and non-virtual functions, working with these memebers
    virtual void func1();
    void func2();

    // no inline functions or friends
};

在这种情况下,更改私有数据成员的顺序是否会破坏 ABI?

class A
{
    string str;
    static const int static_const_number;
    int number; // <--   integer member moved here
    bool b;
    ...
};


编辑
类型没有改变,只有成员的顺序。也没有使用位标志。 该代码用作共享库,没有静态链接到该代码。 我在 Linux 上,编译器是 gcc-3.4.3 和 gcc-4.1

【问题讨论】:

  • 请注意,在您的情况下,您需要声明构造函数和析构函数,因为它们都是内联提供的。
  • @Johannes 是的,它们已被声明,只是在描述中错过了它们。但是感谢您的注意,它很有用。

标签: c++ linux gcc shared-libraries binary-compatibility


【解决方案1】:

是的,如果没有其他原因,A 的大小可能会因数据成员之间的位置和填充字节数的不同而不同。

【讨论】:

    【解决方案2】:

    C++ 没有定义 ABi。这里唯一正确的答案是“这取决于你的编译器”。答案可能是肯定的。

    【讨论】:

      【解决方案3】:

      它可能会在您将实现编译为多个二进制文件的任何地方中断,因为您最终可能会得到两个二进制文件,其中的函数访问不同顺序的私有成员。这包括虚函数的实现,因为它们也可以将其未覆盖的实现编译到多个二进制文件中。

      最好的方法是使用 虚函数,并将它们作为“主机”二进制文件中的接口公开。然后额外的二进制文件不需要实现,所以它们总是在“主机”二进制文件中调用实现,这意味着没有不一致的空间。

      【讨论】:

      • 这是一个共享库,我想它只在一个地方编译,然后在加载它的二进制文件中使用。提示仍然是 10 倍。
      【解决方案4】:

      根据KDE Policies/Binary Compatibility Issues With C++,如果不破坏二进制兼容性,您将无法做到这一点。然而,正如他们的免责声明所述,他们在“你不能......”部分给出的一些建议取决于编译器,所以你可能会摆脱这种变化(尽管不太可能)。

      【讨论】:

      • +1 引用了 KDE Techbase 文章。这无疑是关于网络上 ABI 兼容性的最佳建议集合。
      • @andref,怀疑这是最好的;只是最知名的,我猜 ;-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      相关资源
      最近更新 更多