C static keyword vs C++ private scope?

πάν*_*ῥεῖ -1 c c++

C中翻译单元本地static函数的C++等价是多少?
例如,具有以下内容bar.c:

static void bar() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在C++中,它是否会像一个私有成员函数一样编写

class foo {
    void bar();
};

void foo::bar() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

私有成员函数隐式地将this指针引入为参数,因此它与C样式static函数不具有可比性.但即使是private static成员函数bar()也会在公共接口中看到(并且对于链接器而言仍然可访问),并且也不具有可比性.

虽然这些函数的可访问范围似乎相似,但这些选项看起来不像上面提到的C风格static函数语法的良好替代.

等效于未命名命名空间中的函数,仅对当前转换单元可见吗?

namespace {
    void bar() {
       // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

Bil*_*nch 9

[C]具有文件范围的静态函数.

static void bar() { ... }
Run Code Online (Sandbox Code Playgroud)

这将创建一个名为bar具有内部链接的函数.

[C++]具有文件范围的静态函数

static void bar() { ... }
Run Code Online (Sandbox Code Playgroud)

这将创建一个名为bar具有内部链接的函数.

[C++]未命名的命名空间

namespace {
    void bar() { ... }
}
Run Code Online (Sandbox Code Playgroud)

这将创建一个名为bar具有内部链接的函数.

结论

它们都是完全相同的.我可能建议在C++中使用未命名的命名空间,因为它消除了static关键字的一些重载.但是从你的代码所做的角度来看,这并不重要.

边栏:内部联系意味着什么?

在C和C++中,我们有三种联系:外部,内部无联系.为了定义这些,我将引用C++ 2011第3.5节第2段:

当一个名称可能表示相同的对象,引用,函数,类型,模板,名称空间或值作为另一个范围内的声明引入的名称时,该名称被称为具有链接:

  • 当名称具有外部链接时,其表示的实体可以通过其他翻译单元的范围或同一翻译单元的其他范围中的名称来引用.
  • 当名称具有内部链接时,其表示的实体可以通过同一翻译单元中其他范围的名称来引用.
  • 当名称没有链接时,它表示的实体不能通过其他范围的名称引用.

C 2011在第6.2.2节第2段中有类似的语言:

在构成整个程序的翻译单元和库的集合中,具有外部链接的特定标识符的每个声明表示相同的对象或功能.在一个翻译单元内,具有内部链接的标识符的每个声明表示相同的对象或功能.没有链接的标识符的每个声明表示唯一的实体.

因此,具有内部链接的名称仅在找到它们的翻译单元中可见.

补充工具栏:让我们举一个内部链接在实践中如何工作的示例:

让我们创建2个c ++文件.bar.cc只包含一个内部链接的函数:

static void bar() {}
Run Code Online (Sandbox Code Playgroud)

我们还将创建main.cc,它将尝试使用它bar().

extern void bar();

int main() {
    bar();
}
Run Code Online (Sandbox Code Playgroud)

如果我们编译它,我们的链接器会抱怨.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)
Run Code Online (Sandbox Code Playgroud)

  • @πάνταῥεῖ:我刚试过:`bar.cpp`包含:`static void bar(){}`,而`foo.cpp`包含:`extern void bar(); int main(){bar(); }`.源文件编译为目标文件,没有启用警告; 链接这两个目标文件给了我错误:`架构x86_64的未定义符号:``"bar()",引用自:foo.o`中的_main和架构x86_64`中找不到`ld:symbol(s).QED?(添加了很多警告,编译器抱怨`bar()`已定义但未使用.) (3认同)
  • @πάνταῥεῖ:请提供一个实际示例,该示例可以在描述您所谈论内容的实际编译器中使用:https://gist.github.com/sharth/dc1f30b3918175e7683f (2认同)