使用 "static" 在匿名命名空间中声明函数是否通过不污染符号 table 来减少链接时间和内存

Does declaring functions in anonymous namespace with "static" reduces the linking time and memory by not polluting the symbol table

我正在参加其中一次代码审查会议的讨论。

争论的焦点是匿名命名空间中的函数是否应该声明为静态的。例如,我被告知使用“static”关键字声明的 square3 函数具有优势。

namespace {
int square2(int num) {
    return num * num;
}

static int square3(int num) { 
    return num * num;
}

}

我的同事告诉我静态是有益的,因为:

A static function does not require an entry in the function table and thus does not require time or memory when linking.

static means it is not exposed when linking. It improves linking time and reduces memory usage when linking. Anonymous namespace does not provide this.

我认为我的同事所说的“函数table”是指“符号table”。除了另一个 S.O question 最不赞成的答案外,我找不到任何关于此的文档

It is usually better to prefer static linkage, as that doesn't pollute the symbol table

我正在尝试使用编译器资源管理器查看该信息是否真实。但是我找不到找到符号 table 的方法。我只看到函数名称,所有内容都在 same way.

中被破坏

所以我有两个问题:

1 - 在匿名命名空间中使用带有 static 关键字的函数是否有助于 memory/linking 时间?

2 - 有没有办法在编译器资源管理器中检查符号 table?

1 - Is using a function with static keyword in the anonymous namespace helps with memory/linking time?

就语言而言,静态不会影响匿名命名空间中的函数。这是因为在匿名命名空间中已经实现了与声明函数静态实现的相同的东西。 (注意声明一个成员函数static有完全不同的含义)

2 - Is there a way to check the symbol table in compiler explorer?

我不知道编译器资源管理器,但是您可以使用例如 nm 程序来列出符号:http://coliru.stacked-crooked.com/a/0281bc487044ec02

namespace {

       void foo1(){} // internal linkage
static void foo2(){} // internal linkage

}

       void foo3(){} // external linkage
static void foo4(){} // internal linkage

命令:

nm main.o | c++filt

输出:

0000000000000000 T foo3()

It improves linking time and reduces memory usage when linking.

即使对于给定的实现来说是这样,从纯语言的角度来看,未命名命名空间中的静态函数也是多余的,并且可以说是一种可能会使其他开发人员感到困惑的反模式;谁可能已经与 C++ 超载的方式作斗争 static 链接 和完全正交的 存储持续时间 .[= 方面意味着什么14=]

// .cpp
namespace top {

       int a{};  // external linkage, static storage duration
const  int b{};  // internal linkage, static storage duration
static int c{};  // internal linkage, static storage duration

namespace {

       int d{};  // internal linkage, static storage duration
const  int e{};  // internal linkage, static storage duration
static int f{};  // internal linkage, static storage duration
// ^^^ static is redundant (-> and may confuse devs)

       int g() {}  // internal linkage
static int h() {}  // internal linkage
// ^^^ static is redundant (-> and may confuse devs)

}  // namespace

       int k() {}  // external linkage
static int l() {}  // internal linkage

}  // namespace top

[...] except the least upvoted answer of another S.O question which says

It is usually better to prefer static linkage, as that doesn't pollute the symbol table

您提到的答案基于 C++03,其中未命名命名空间中的实体默认没有内部链接。这意味着在 C++03 中,即使未命名命名空间中的实体对其他翻译单元 不可访问 (由于未命名命名空间的独特命名性质),它仍然可以具有外部链接,因此以符号 table.

结尾

从 C++11 开始 未命名命名空间中的实体具有内部链接。也就是说,从 C++ 语言的角度来看 w.r.t。链接,上面的例子(带有内部链接)是等价的,甚至可以说你的同事混合了这些概念(由于它们的含义过载而很常见)或者你同事的论点是基于事态在 C++11 之前。