可以使用内联命名空间来保持共享库中的向后兼容性? [英] Can inline namespaces be used to keep backwards compatibility in a shared library?

查看:556
本文介绍了可以使用内联命名空间来保持共享库中的向后兼容性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++内联命名空间的基本原理是源和二进制兼容性(参见Herb Sutter的论文 N2535 ),但在引入内联命名空间时,我还无法找到现有库的保留二进制兼容性的好例子,是可能的。



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



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



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

  struct ModelA 
{
/ *(...)很多东西* /
};

struct ModelB
{
/ *(...)很多东西* /
};我们可以使用内联命名空间来引入结构体/类的新版本,而不会破坏客户端(例如,替换成一个新的结构体)。



<

  inline命名空间mylib 
{

inline namespace v1
{
struct ModelA
{
/ *(...)很多东西* /
};
} // end namespace v1

namespace v2
{
struct ModelA
{
/ *(...) + newstuff * /
};
} // end namespace v2

struct ModelB
{
/ *(...)很多东西* /
};

} // end namespace mylib

如果没有,包含的内联命名空间mylib?

解决方案

不是真正的答案,但可能会导致一个答案。 >

gcc 4.8.2 下测试两个简单来源:

 命名空间n1 
{
void f1(int);

inline命名空间n2
{
void f2(int);
}
}

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

没有inline命名空间:

 命名空间n1 
{
void f1(int);
void f2(int);
}

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

然后使用 objdump -t



第一个版本的结果( inline命名空间):

  _ZN2n12f1Ei 
_ZN2n12n22f2Ei


$ b b

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

  _ZN2n12f1Ei 
_ZN2n12f2Ei

您可以看到 f2 不同(第一个包括 n2 命名空间的名称)。这意味着如果你使用 gcc ,你不能只是用一个带有内联命名空间的新库来替换你的库。我不会指望一些其他编译器会做另一种方式(保存二进制兼容内联命名空间)。


The rationale for C++'s inline namespaces is both source and binary compatibility (see Herb Sutter's paper linked in N2535), but I have not been able to find good examples of keeping binary compatibility for existing libraries when introducing inline namespaces, or if it is possible.

(for more info, and examples of source compatibility, see this question)

(for solving a related problem, using inline namespace to introduce incompability, see this question)

If this is our current library (e.g. mylib.dll), which is shared with clients and need to be stable:

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

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

Can we use inline namespaces to introduce new versions of the structs/classes without breaking the clients (i.e. replace the shared library file (mylib.dll) only, no recompile neccessary)?

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

If not, will it work without the enclosing inline namespace mylib?

解决方案

Not really an answer to your question, but probably can lead to an answer.

Tested under gcc 4.8.2 with two simple sources:

namespace n1
{
   void f1 (int);

   inline namespace n2
   {
      void f2 (int);
   }
}

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

And without inline namespace:

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

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

Then inspected mangled names of symbols in compiled object files using objdump -t.

Results for the first version (with inline namespace):

_ZN2n12f1Ei
_ZN2n12n22f2Ei

Second version (without inline namespace):

_ZN2n12f1Ei
_ZN2n12f2Ei

You can see that the mangled name of f2 differs (the first one includes the name of n2 namespace). It means that in case you are using gcc, you cannot just replace your library with a new one with inlined namespaces. I won't expect that some other compiler will do it another way (save binary compatibility with inline namespaces).

这篇关于可以使用内联命名空间来保持共享库中的向后兼容性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆