C++和二进制兼容性:按值返回 POD 结构
考虑以下 C++ 代码:
struct X
{
int a;
int b;
};
X foobar()
{
X x = { 1, 2 };
return x;
}
现在假设此代码放入共享库中,由第三方应用程序使用。
我的问题是:如果我在 X
末尾添加另一个成员(例如 int c
),并在 foobar()
中初始化它,将会调用 foobar() 的现有应用程序会中断吗?请注意,这是关于二进制兼容性,而不是源兼容性。
Consider the following C++ code:
struct X
{
int a;
int b;
};
X foobar()
{
X x = { 1, 2 };
return x;
}
Now assume this code is put in a shared library, which is used by third-party applications.
My question is: if I add another member at the end of X
(e.g. int c
), and initialize it in foobar()
, will existing applications which call foobar()
break? Note that this is about binary compatibility, not source compatibility.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这完全取决于您的编译器选择做什么(更具体地说,平台 ABI 规定了什么)。
您可以想象,如果将返回值放置在堆栈上,那么您现在在堆栈上写入的内容将比调用者预期的要多,这可能会导致在某些内容上留下痕迹。
一般来说,您不应该依赖任何特定行为。您只需重新编译客户端应用程序即可。唯一现实的替代方案是类似于 PIMPL 惯用法。
It depends entirely on what your compiler chooses to do (more specifically, what the platform ABI dictates).
You can imagine that if the return value is placed on the stack, you would now be writing more onto the stack than the caller is expecting, which may result in stamping on something.
In general, you shouldn't rely on any particular behaviour. You simply must re-compile the client applications. The only realistic alternative is something like the PIMPL idiom.
因为 X 的大小会改变,是的。数组等取决于大小。您可能会“幸运”,并且填充可能允许较旧的应用程序使用较新的库,但这纯粹是运气。
Since the size of X would change, yes. Arrays and such depend on sizes. You might get "lucky" and padding might allow older apps to use the newer lib but it would be pure luck.