在 d 指针类中添加新成员函数是否会破坏二进制兼容性?
在 d 指针类定义中添加新成员函数是否会破坏二进制兼容性?
例如,与原始定义相比,下面的新定义是否会破坏二进制兼容性? (附带问题,是否有一个工具可以告诉我新的 .so 与旧的 .so 相比是否破坏了二进制兼容性?如果没有,我如何手动检查?)
原文:
#ifndef __TESTBC_H__
#define __TESTBC_H__
class APrivate;
class A
{
public:
int get() { d->update(); return _d->get(); }
private:
APrivate *_d;
};
class APrivate
{
public:
int get() { return _val; }
void update() { _val = 1; }
private:
int _val;
};
#endif
新:
#ifndef __TESTBC_H__
#define __TESTBC_H__
class APrivate;
class A
{
public:
int get() { _d->update(); return _d->get(); }
private:
APrivate *_d;
};
class APrivate
{
public:
int get() { return _val; }
void update() { _val = 1; multiply(); }
void multiply() { _val = _val * 10; }
private:
int _val;
};
#endif
仅供参考:我理解 d 指针类应该是在 cc 文件而不是 header 中指定。 上面的示例旨在关注二进制兼容性问题。
Will adding new member function into d pointer class definition break binary compatibility?
For example, will the new definition below break binary compatibility compared to the original? (side question, is there a tool that will tell me if a new .so breaks binary compatibility compared to the old .so? If not, how do I check manually?)
Original:
#ifndef __TESTBC_H__
#define __TESTBC_H__
class APrivate;
class A
{
public:
int get() { d->update(); return _d->get(); }
private:
APrivate *_d;
};
class APrivate
{
public:
int get() { return _val; }
void update() { _val = 1; }
private:
int _val;
};
#endif
New:
#ifndef __TESTBC_H__
#define __TESTBC_H__
class APrivate;
class A
{
public:
int get() { _d->update(); return _d->get(); }
private:
APrivate *_d;
};
class APrivate
{
public:
int get() { return _val; }
void update() { _val = 1; multiply(); }
void multiply() { _val = _val * 10; }
private:
int _val;
};
#endif
FYI: I understand d pointer class should be specified in the cc file instead of header. above example is contrived to focus on binary compatibility issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,不是的。
您应该了解 C++ 如何构建其对象。
在你的例子中,它几乎是带有非虚拟成员函数的“POD”类。 这些
函数不影响对象在内存中的表示。 因此新版本
与旧版本二进制兼容。
更重要的是,如果您不向用户公开您的“APrivate”类。 (不给
头只是前向声明),即使你做得更大,你也不会阻止 API
变化。
含义:
您甚至不公开
bar
,因此您可以按照您希望的任何方式更改它。 它是使 C++ 库 ABI 兼容的最佳方法。
No it does not.
You should understand how C++ builds its objects.
In your case it is just almost "POD" class with non-virtual member functions. These
functions do not affet the representation of object in memory. Thus new version
is binary compatible with old.
More then that, if you do not expose your "APrivate" class to user. (Not giving
a header just forward declaration), you would not brake an API even if you do much bigger
changes.
Meaning:
You do not even expose
bar
so you may change it in any way you wish. it is thebest way to make C++ libraries ABI compatible.
考虑使用 abi-compliance-checker 工具,它检查头文件和共享库并搜索可能破坏二进制兼容性的 ABI 更改。
Consider using the abi-compliance-checker tool, it checks header files and shared libs and searches for ABI changes that may break binary compatibility.