C静态关键字与C++私有作用域

C static keyword vs C++ private scope?

本文关键字:作用域 C++ 静态 关键字      更新时间:2023-10-16

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() {
       // ...
    }
}

[C]具有文件作用域的静态函数

static void bar() { ... }

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

[C++]具有文件作用域的静态函数

static void bar() { ... }

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

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

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翻译单元中找不到名为CCD_ 13的函数。这是内部链接的预期行为。

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)