为了账号安全,请及时绑定邮箱和手机立即绑定

什么是内联命名空间?

什么是内联命名空间?

C++
梵蒂冈之花 2019-08-29 17:02:39
什么是内联命名空间?C ++ 11允许inline namespaces,其所有成员也自动在封闭中namespace。我想不出任何有用的应用 - 有人可以给出一个简短,简洁的例子,说明inline namespace需要哪种情况以及最常用的解决方案?(另外,当发生了什么并不清楚,我namespace声明inline在一个但不是所有的声明,这可能住在不同的文件。这难道不是找麻烦?)
查看完整描述

3 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

除了上面的所有答案。

内联命名空间可用于编码符号中的ABI信息或函数版本。正是由于这个原因,它们被用于提供后向ABI兼容性。内联命名空间允许您在不更改API的情况下将信息注入到损坏的名称(ABI)中,因为它们仅影响链接器符号名称。

考虑这个例子:

假设您编写了Foo一个引用对象的函数,bar并且不返回任何内容。

在main.cpp中说

struct bar;void Foo(bar& ref);

如果在将文件编译为对象后检查此文件的符号名称。

$ nm main.o
T__ Z1fooRK6bar

链接器符号名称可能会有所不同,但它肯定会在某处编码函数和参数类型的名称。

现在,它可能被bar定义为:

struct bar{
   int x;#ifndef NDEBUG   int y;#endif};

根据构建类型,bar可以引用具有相同链接器符号的两种不同类型/布局。

为了防止这种行为,我们将结构包装bar到一个内联命名空间中,根据Build类型,链接器符号bar将是不同的。

所以,我们可以写:

#ifndef NDEBUGinline namespace rel { #elseinline namespace dbg {#endifstruct bar{
   int x;#ifndef NDEBUG   int y;#endif};}

现在,如果您查看每个对象的目标文件,您可以使用release构建一个,另一个使用debug flag。您会发现链接器符号也包含内联命名空间名称。在这种情况下

$ nm rel.o
T__ ZROKfoo9relEbar$ nm dbg.o
T__ ZROKfoo9dbgEbar

链接器符号名称可能不同。

注意符号名称的存在reldbg符号名称。

现在,如果您尝试将调试与发布模式链接或反之亦然,则会出现链接器错误,这与运行时错误相反。


查看完整回答
反对 回复 2019-08-29
  • 3 回答
  • 0 关注
  • 830 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信