C中翻译单元本地static
函数的C ++等价是什么?
例如,在bar.c
中包含以下内容:
static void bar() {
// ...
}
在C ++中,它是否会像
这样的私有成员函数编写class foo {
void bar();
};
void foo::bar() {
// ...
}
私有成员函数隐式地将this
指针引入为参数,因此它与C样式static
函数无法真正比较。但即使是private static
成员函数bar()
也会在公共接口中看到(并且对于链接器仍然可访问),并且也不具有可比性。
虽然这些函数的可访问范围似乎相似,但这些选项看起来不像上面提到的C样式static
函数语法的替代品。
等效于未命名命名空间中的函数,仅对当前翻译单元可见吗?
namespace {
void bar() {
// ...
}
}
答案 0 :(得分:9)
static void bar() { ... }
这将创建一个名为bar
的函数,该函数具有内部链接。
static void bar() { ... }
这将创建一个名为bar
的函数,该函数具有内部链接。
namespace {
void bar() { ... }
}
这将创建一个名为bar
的函数,该函数具有内部链接。
他们都相同。我可能建议在C ++中使用未命名的命名空间,因为它消除了static
关键字的一些重载。但是从你的代码的角度来看,这并不重要。
在C和C ++中,我们有三种链接:外部,内部和无链接。为了定义这些,我将引用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();
}
如果我们编译它,我们的链接器会抱怨。我们可以从main.cc翻译单元找到名为bar
的函数。这是内部联系的预期行为。
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)