【问题标题】:Should unnamed namespace functions be avoided to reduce symbol table sizes?是否应该避免使用未命名的命名空间函数来减少符号表的大小?
【发布时间】:2013-01-17 18:16:47
【问题描述】:

我听说它断言在 C++ 中使用未命名的命名空间来定义函数并确保不能从定义它们的编译单元外部调用它们在非常大的代码环境中不好,因为它们会导致符号通过在 C++ 编译器在未命名时提供的自动生成的命名空间中包含这些符号的条目,表会变得不必要地变大。

namespace {
  // This function can only be accessed from hear to the end of 
  // any compilation unit that includes it.
  void functionPerhapsInsertedIntoSymbolTable() {
    return;
  }
}

这可能是因为上面应该与执行以下操作相同:

namespace randomlyGenerateNameHereNotCollidingWithAnyExistingNames {
  // This function can only be accessed from hear to the end of
  // any compilation unit that includes it.
  void functionPerhapsInsertedIntoSymbolTable() {
    return;
  }
}
using randomlyGenerateNameHereNotCollidingWithAnyExistingNames;

但是,真的那么简单吗,编译器是否需要为生成的命名空间名称中的符号建立一个符号表项?

相反,在这种情况下,我听说它建议使用静态声明:

// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
static void functionNotInsertedIntoSymbolTable() {
  return;
}

在函数之前使用静态声明而不是将其放置在未命名的命名空间中是否具有使函数在定义它的编译单元之外无法访问的相同效果?除了可能不会导致符号表增长之外,这两种方法之间有什么区别吗?

由于未命名的命名空间导致的符号表膨胀问题只是 C++ 的某些实现中的一个错误,还是标准要求编译器以某种方式为此类函数创建条目?如果这种膨胀被认为是一个错误,是否有已知的编译器不存在这问题?

【问题讨论】:

  • 您也可以只使用f(x)g(y) 之类的名称来减小符号表的大小,但这也不是一个好主意。
  • 你有没有证据支持未命名的命名空间膨胀符号表的断言?
  • 公司其他开发者声称,本人没有亲身经历。我们还没有使用 C++11。
  • 为什么投反对票?如果这是真的,最好知道静态方法是否可以防止问题。如果它是错误的,那么最好有一个可靠的答案我们可以用作参考......

标签: c++ language-lawyer symbol-table unnamed-namespace


【解决方案1】:

在函数之前使用静态声明而不是将其放置在未命名的命名空间中是否具有使函数在定义它的编译单元之外无法访问的相同效果?

是的。

命名空间-static 在 C++03 中被弃用,取而代之的是未命名的命名空间,但实际上 un-deprecated for C++11 当每个人都意识到它们只是同一个东西并且没有任何弃用的目的时。

这两种方法有什么区别

不,不是真的。由于使用了命名空间,名称查找可能会有一些细微之处,但我现在想不出。

除了可能不会导致符号表增长之外?

由于这是一个language-lawyer 的问题,没有明显的实际问题需要解决,我不得不指出,C++ 语言没有符号表的概念,因此没有这种效果的迹象。

在您拥有数以万计的未命名命名空间之前,它也不会产生任何明显的影响;你呢?

【讨论】:

  • “由于这是一个语言律师问题……我有义务指出……”仅此一项就值得点赞。 :-D
【解决方案2】:

未命名的命名空间和命名空间级别静态的弃用的原因是命运多舛的导出关键字。

导出的模板所依赖的所有内容都必须在实例化点可链接访问,这很可能在不同的源文件中。未命名的命名空间允许静态的“私有化”方面,同时仍保留导出模板的链接。

现在导出已在 C++2011 中删除,我很确定未命名命名空间的外部链接要求已被删除,它现在的行为与命名空间级别的静态完全相同。更熟悉该标准的人可以证实/反驳这一点。

【讨论】:

  • [C++11 3.5/4] 提供未命名的命名空间内部链接;到目前为止,我找不到任何证据表明 C++03 中不是这种情况,尽管措辞要复杂得多。
  • [C++03 3.5/4] 似乎确实暗示名称 within 名称空间具有外部链接,除非在一堆不包括在未命名名称空间中的情况下,除非名称本身是命名空间。
猜你喜欢
  • 2021-11-02
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 2018-01-21
  • 2021-05-03
  • 1970-01-01
  • 2017-05-28
相关资源
最近更新 更多