可以使用内联命名空间来保持共享库中的向后兼容性吗?

时间:2015-04-21 06:48:57

标签: c++ c++11 abi binary-compatibility

C ++内联命名空间的基本原理是源代码和二进制兼容性(参见N2535中链接的Herb Sutter论文),但我找不到好的例子引入内联命名空间时,保持现有库的二进制兼容性,或者是否可能。

(有关更多信息和源兼容性示例,请参阅this question

(为解决相关问题,使用内联命名空间引入不兼容性,请参阅this question

如果这是我们当前的库(例如mylib.dll),它与客户共享并且需要稳定:

struct ModelA
{
   /* (...) lots of stuff */
};

struct ModelB
{
   /* (...) lots of stuff */
};

我们是否可以使用内联命名空间来引入新版本的结构/类而不会破坏客户端(即仅替换共享库文件(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

如果没有,它是否可以在没有封闭内联命名空间mylib的情况下工作?

1 个答案:

答案 0 :(得分:2)

不是你问题的答案,但可能会得到答案。

使用两个简单的来源在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);
}

没有内联命名空间:

namespace n1
{
   void f1 (int);
   void f2 (int);
}

void f (int x)
{
   n1::f1(x);
   n1::f2(x);
}

然后使用objdump -t检查编译对象文件中符号的错位名称。

第一个版本的结果(带有内联命名空间的):

_ZN2n12f1Ei
_ZN2n12n22f2Ei

第二个版本(不带内联命名空间):

_ZN2n12f1Ei
_ZN2n12f2Ei

您可以看到错误的f2名称不同(第一个包含n2命名空间的名称)。这意味着如果您使用gcc,则不能仅使用带有内联命名空间的新库替换您的库。我不希望其他一些编译器会以另一种方式执行它(保存与内联命名空间的二进制兼容性)。