将新的成员函数添加到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
Run Code Online (Sandbox Code Playgroud)
新:
#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() …Run Code Online (Sandbox Code Playgroud) 有人可以向我解释为什么在类声明的末尾添加一个虚函数可以避免二进制不兼容吗?
如果我有:
class A
{
public:
virtual ~A();
virtual void someFuncA() = 0;
virtual void someFuncB() = 0;
virtual void other1() = 0;
private:
int someVal;
};
Run Code Online (Sandbox Code Playgroud)
然后将此类声明修改为:
class A
{
public:
virtual ~A();
virtual void someFuncA() = 0;
virtual void someFuncB() = 0;
virtual void someFuncC() = 0;
virtual void other1() = 0;
private:
int someVal;
};
Run Code Online (Sandbox Code Playgroud)
我得到了另一个coredump.所以根据之前的声明编译.但是如果我在类声明的末尾放置someFuncC()(在"int someVal"之后):
class A
{
public:
virtual ~A();
virtual void someFuncA() = 0;
virtual void someFuncB() = 0;
virtual void other1() = …Run Code Online (Sandbox Code Playgroud) 如果我在 Ubuntu 上得到一些由 GCC 4.8 构建的 C++ 代码,该代码没有 GUI/界面,仅调用标准 Linux 库,那么该二进制文件可以在 RHEL 5/6 上完美运行,并且可以与更旧的 GCC 一起完美运行吗?
我有.NET代码使用的vb6 com服务器(ActiveX DLL项目)
每次我将更改放入vb6代码并生成dll时,我也必须重新编译我的.NET客户端代码,因为它看起来像VB6为接口和com对象生成新的GUID或版本.
我承认这是一个很好的做法,因为进行了更改,但我想禁用此行为,以便每次更新我的vb6 dll时都让我的.NET客户端代码相同.
无论对COM对象或COM接口做了哪些更改,我如何告诉VB6保持ActiveX dll的所有GUID和版本都一样?
这个问题是作为这个问题的后续问题:C++中指针变量和引用变量之间有什么区别?
阅读了我在stackoverflow上找到的答案和一些进一步的讨论后,我知道编译器应该像处理pass-by-pointer一样对待pass-by-reference,而引用只不过是语法糖.考虑到二进制兼容性,如果存在任何差异,我还无法弄清楚一件事.
在我们的(多平台)框架中,我们要求在发布和调试版本之间(以及框架的不同版本之间)进行二进制兼容.特别是,我们在调试模式下构建的二进制文件必须可用于发布版本,反之亦然.为此,我们只在接口中使用纯抽象类和POD.
请考虑以下代码:
class IMediaSerializable
{
public:
virtual tResult Serialize(int flags,
ISerializer* pSerializer,
IException** __exception_ptr) = 0;
//[…]
};
Run Code Online (Sandbox Code Playgroud)
ISerializer并且IException也是纯粹的抽象类.ISerializer必须指向现有对象,因此我们总是必须执行NULL指针检查.IException实现某种异常处理,其中指针指向的地址必须改变.出于这个原因,我们使用指向指针的指针,指针也必须是NULL指针.
为了使代码更清晰并省去一些不必要的运行时检查,我们希望使用pass-by-reference重写此代码.
class IMediaSerializable
{
public:
virtual tResult Serialize(int flags,
ISerializer& pSerializer,
IException*& __exception_ptr) = 0;
//[…]
};
Run Code Online (Sandbox Code Playgroud)
这似乎没有任何缺陷.但问题仍然是我们是否仍然满足二进制兼容性的要求.
更新: 澄清事情:这个问题不是关于代码的pass-by-pointer版本和pass-by-reference版本之间的二进制兼容性.我知道这不能是二进制兼容的.事实上,我们有机会重新设计我们的API,我们考虑使用pass-by-reference而不是pass-by-pointer而不关心二进制兼容性(新的主要版本).问题只是关于仅使用代码的pass-by-reference版本的二进制兼容性.
c++ interface-design pass-by-reference binary-compatibility pass-by-pointer
假设共享库包含以下行:
const char* const arr[] =
{
"one",
"two",
"three"
};
Run Code Online (Sandbox Code Playgroud)
1)应用程序是否可以链接到此库并使用符号"arr"?
2)如果在定义中添加了新元素,二进制兼容性是否会被破坏?
3)如果其中一个字符串文字被更改了怎么样?
4)为什么(不)?
干杯,卢克
我的项目使用2个不同的C++编译器,g ++和nvcc(cuda编译器).我注意到从nvcc对象文件抛出的异常没有被g ++对象文件捕获.
C++异常是否应该在同一台机器上兼容二进制?什么可以导致这种行为?
try { kernel_= new cuda:: Kernel(); }
catch (...) { kernel_= NULL; }
// nvcc object
cuda:: Kernel:: Kernel () {
...
if (! impl_) throw;
}
Run Code Online (Sandbox Code Playgroud)
其他一切似乎都有效(C++对象,运算符).说实话,我不太了解异常,所以上面的代码可能有错误.
如果我有在Solaris 8和10下编译的代码,现在有一个供应商想在Linux下使用我的bin/exe.可能存在兼容性问题吗?
我很确定我需要在Linux操作系统下编译/链接才能100%工作但我只是想知道是否有人可以告诉我为什么它不能在Linux上工作,即使exe有所有东西也在那里没有任何动态,因为它不需要任何进一步的运行它.除非我们讨论运行时库,否则如果存在不匹配可能会导致exe失败.
什么改变或代码进化破坏了向后兼容性(主要是二进制兼容性)在任何地方都完全指定了吗
我检查了Scala语言规范,但没有看到任何关于Java语言规范Ch的问题.13二进制兼容性.