mea*_*stp 5 c++ abi binary-compatibility c++11
C++ 内联命名空间的基本原理是源代码和二进制兼容性(请参阅N2535中链接的 Herb Sutter 的论文),但在引入内联命名空间时,或者如果可能的话,我无法找到保持现有库的二进制兼容性的好示例。
(有关更多信息以及源兼容性的示例,请参阅此问题)
(为了解决相关问题,使用内联命名空间引入不兼容,请参阅这个问题)
如果这是我们当前的库(例如 mylib.dll),与客户端共享并且需要稳定:
struct ModelA
{
/* (...) lots of stuff */
};
struct ModelB
{
/* (...) lots of stuff */
};
Run Code Online (Sandbox Code Playgroud)
我们是否可以使用内联命名空间引入新版本的结构/类而不破坏客户端(即仅替换共享库文件(mylib.dll),无需重新编译)?
inline namespace mylib
{
inline namespace v1
{
struct ModelA
{
/* (...) lots of stuff */
};
} // end namespace v1
namespace v2
{
struct ModelA
{
/* (...) lots of stuff + newstuff */
};
} // end namespace v2
struct ModelB
{
/* (...) lots of stuff */
};
} // end namespace mylib
Run Code Online (Sandbox Code Playgroud)
如果没有,那么在没有封闭的内联命名空间 mylib 的情况下它还能工作吗?
并不是你问题的真正答案,但可能可以找到答案。
gcc 4.8.2使用两个简单来源进行测试:
namespace n1
{
void f1 (int);
inline namespace n2
{
void f2 (int);
}
}
void f (int x)
{
n1::f1(x);
n1::f2(x);
}
Run Code Online (Sandbox Code Playgroud)
并且没有内联名称空间:
namespace n1
{
void f1 (int);
void f2 (int);
}
void f (int x)
{
n1::f1(x);
n1::f2(x);
}
Run Code Online (Sandbox Code Playgroud)
然后使用 . 检查编译目标文件中符号的损坏名称objdump -t。
第一个版本的结果(带有内联命名空间):
_ZN2n12f1Ei
_ZN2n12n22f2Ei
Run Code Online (Sandbox Code Playgroud)
第二个版本(没有内联命名空间):
_ZN2n12f1Ei
_ZN2n12f2Ei
Run Code Online (Sandbox Code Playgroud)
您可以看到 的 损坏名称有所f2不同(第一个包括命名空间的名称n2)。这意味着,如果您正在使用gcc,则不能仅将您的库替换为具有内联名称空间的新库。我不希望其他编译器会以另一种方式执行此操作(保存与内联命名空间的二进制兼容性)。