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

C的内联命名空间的基本原理是源代码和二进制兼容性(参见Herb Sutter在
N2535中链接的文章),但是在引入内联命名空间时,或者如果是这样,我无法找到保持现有库的二进制兼容性的好例子.可能.

(有关更多信息和源兼容性示例,请参阅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吗?

最佳答案 不是你的问题的答案,但可能会导致答案.

在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,则不能仅使用带有内联命名空间的新库替换您的库.我不希望其他一些编译器会以另一种方式执行它(保存与内联命名空间的二进制兼容性).

点赞