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

2024-01-12

C++ 内联命名空间的基本原理是源代码和二进制兼容性(请参阅 Herb Sutter 的论文,链接为N2535 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm),但我还没有找到好的例子keeping引入内联命名空间时或如果可能的话,现有库的二进制兼容性。

(有关更多信息以及源兼容性的示例,请参阅这个问题 https://stackoverflow.com/questions/11016220/what-are-inline-namespaces-for)

(为了解决相关问题,使用内联命名空间引入不兼容,请参见这个问题 https://stackoverflow.com/questions/8454329/why-cant-clang-with-libc-in-c0x-mode-link-this-boostprogram-options-examp/8457799#8457799)

如果这是我们当前的库(例如 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.

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

_ZN2n12f1Ei
_ZN2n12n22f2Ei

第二版(without内联命名空间):

_ZN2n12f1Ei
_ZN2n12f2Ei

您可以看到损坏的名称f2不同(第一个包括名称n2命名空间)。这意味着如果您正在使用gcc,您不能只是将您的库替换为具有内联名称空间的新库。我不希望其他编译器会以另一种方式执行此操作(保存与内联命名空间的二进制兼容性)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内联命名空间可以用来保持共享库的向后兼容性吗? 的相关文章

随机推荐