[C] 具有文件作用域的静态函数。
static void bar() { ... }
这将创建一个名为的函数bar
具有内部联系。
[C++] 具有文件作用域的静态函数
static void bar() { ... }
这将创建一个名为的函数bar
具有内部联系。
[C++] 未命名命名空间
namespace {
void bar() { ... }
}
这将创建一个名为的函数bar
具有内部联系。
结论
他们都是完全相同的。我可能会建议在 C++ 中使用未命名的命名空间,因为它消除了一些重载static
关键词。但从代码的作用来看,这并不重要。
侧边栏:内部链接是什么意思?
在 C 和 C++ 中,我们有三种链接:External, Internal and 无联动。为了定义这些,我将引用 C++ 2011 第 3.5 节第 2 段:
当一个名称可能表示与另一个作用域中的声明引入的名称相同的对象、引用、函数、类型、模板、命名空间或值时,则称该名称具有链接:
- 当名称具有外部链接时,它所表示的实体可以通过其他翻译单元范围或同一翻译单元的其他范围的名称来引用。
- 当名称具有内部链接时,它所表示的实体可以被同一翻译单元中其他范围的名称引用。
- 当名称没有链接时,它所表示的实体不能被其他范围的名称引用。
C 2011 在第 6.2.2 节第 2 段有类似的语言:
在构成整个程序的翻译单元和库的集合中,具有外部链接的特定标识符的每个声明都表示相同的对象或函数。在一个翻译单元内,具有内部链接的标识符的每个声明都表示相同的对象或函数。没有链接的标识符的每个声明都表示一个唯一的实体。
因此,具有内部链接的名称仅在找到它们的翻译单元中可见。
侧边栏:让我们举一个内部链接在实践中如何工作的示例:
让我们创建 2 个 c++ 文件。bar.cc将仅包含一个具有内部链接的函数:
static void bar() {}
我们还将创建main.cc,它将尝试使用它bar()
.
extern void bar();
int main() {
bar();
}
如果我们编译它,我们的链接器会抱怨。没有名为的函数bar
我们可以从 main.cc 翻译单元中找到。这是内部链接的预期行为。
Undefined symbols for architecture x86_64:
"bar()", referenced from:
_main in main-c16bef.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)