未命名名称空间中名称的外部链接 [英] External linkage for name inside unnamed namespace

查看:109
本文介绍了未命名名称空间中名称的外部链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据C ++ Standard的第3.5 / 4条:

According to the clause 3.5/4 of C++ Standard:


未命名的名称空间或直接或间接声明的名称空间

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage.

同时在第7.3.1.1段中,我们有注96):

Simultanously in paragraph 7.3.1.1 we have note 96):


尽管未命名命名空间中的实体可能具有外部链接,但是
实际上通过其转换
单元的唯一名称来限定,因此永远

Although entities in an unnamed namespace might have external linkage, they are effectively qualified by a name unique to their translation unit and therefore can never be seen from any other translation unit.

如何在未命名的命名空间中显式建立外部链接,以及如何检查链接是否真正存在如果Standard保证没有办法从另一个翻译单元访问未命名空间中定义的名称?

How to explicitly make external linkage for name inside unnamed namespace and how to check that linkage is actually external if Standard guaranteed that there is no way to access name defined inside unnamed namespace from another translation unit?

在这种情况下,对未命名空间中的名称进行显式外部链接很有用?

In which cases doing explicit external linkage for name inside unnamed namespace is useful?

推荐答案


如何显式建立未命名命名空间中名称的外部链接

How to explicitly make external linkage for name inside unnamed namespace

想到的是给它C语言链接,以便其链接名称忽略名称空间限定:

The only way I can think of is to give it C language linkage, so that its linkage name ignores the namespace qualification:

namespace {
  extern void f() { }      // has internal linkage despite 'extern'
  extern "C" void g() { }  // ignores linkage of namespace
}
void (*p)() = f;  // ensure 'f' won't be optimized away

(严格阅读该标准表明, g 应该具有内部链接,但是编译器似乎没有这样做。)

(A strict reading of the standard suggests that g should have internal linkage, but that's not what compilers seem to do.)


以及如果Standard保证无法从另一个翻译单元访问未命名空间中定义的名称,又如何检查链接实际上是外部的?

and how to check that linkage is actually external if Standard guaranteed that there is no way to access name defined inside unnamed namespace from another translation unit?

通常,ELF编译器将使用非全局符号实现内部链接,因此您可以编译代码并检查目标文件:

Typically ELF compilers will implement internal linkage with non-global symbols, so you can compile the code and inspect the object file:

$ g++ -c linkage.cc
$ nm linkage.o
0000000000000000 t _ZN12_GLOBAL__N_11fEv
0000000000000007 T g
0000000000000000 D p

在编译器之间,未命名空间的错误名称可能有所不同,但对其进行拆解将显示:

The mangled name of the unnamed namespace can vary between compilers, but demangling it will show:

$ nm -C  linkage.o
0000000000000008 t (anonymous namespace)::f()
0000000000000000 T g
0000000000000000 D p

小写字母 t 显示 f 具有本地可见性,这意味着它不能从其他目标文件链接到。大写的 T 显示 g 具有外部链接。

The lowercase t shows that f has local visibility, meaning it can't be linked to from other object files. The uppercase T shows that g has external linkage.

但这不是标准所保证的,因为ELF可见性不是C ++标准的一部分,并且某些编译器甚至在ELF平台上也实现了不使用可见性的链接。 EDG编译器会为同一代码生成一个全局符号:

This isn't guaranteed by the standard though, as ELF visibility is not part of the C++ standard, and some compilers implement linkage without using visibility even on ELF platforms, e.g. the EDG compiler produces a global symbol for the same code:

$ nm linkage.o
0000000000000008 T _ZN23_GLOBAL__N__7_link_cc_p1fEv
0000000000000004 C __EDGCPFE__4_9
0000000000000000 T g
0000000000000000 D p
$ nm -C linkage.o
0000000000000008 T (anonymous namespace)::f()
0000000000000004 C __EDGCPFE__4_9
0000000000000000 T g
0000000000000000 D p

因此使用 extern C 允许您提供名称外部链接,即使它出现在未命名的命名空间中,也不能使注释正确,因为您可以从其他翻译单元引用该名称,因为它不使用未命名的命名空间范围。这向我表明,当未命名的命名空间中的实体没有自动内部链接时,该注释只是C ++ 03的剩余部分,因此应更正或删除该注释(实际上TC指出该注释已由 DR 1603 )。

So using extern "C" allows you to give a name external linkage even if it appears in an unnamed namespace, but that doesn't make the note correct, because you can refer to that name from other translation units, because it doesn't use the unnamed namespace scope. That suggests to me that the note is simply a leftover from C++03 when entities in unnamed namespaces didn't automatically have internal linkage, and the note should be corrected or removed (and indeed T.C. points out it was already removed by DR 1603).


在在未命名的名称空间中对名称进行显式外部链接的情况有用吗?

In which cases doing explicit external linkage for name inside unnamed namespace is useful?

我想不出在任何情况下有用的情况。

I can't think of any cases where it's useful.

这篇关于未命名名称空间中名称的外部链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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