C static keyword vs C++ private scope?

[C] Static function with file scope.

static void bar() { ... }

This will create a function named bar that has internal linkage.

[C++] Static function with file scope

static void bar() { ... }

This will create a function named bar that has internal linkage.

[C++] Unnamed namespace

namespace {
    void bar() { ... }
}

This will create a function named bar that has internal linkage.

Conclusions

They are all identical. I’d probably recommend using the unnamed namespace in C++, because it gets rid of some of the overloading of the static keyword. But from the perspective of what your code does, it doesn’t matter.

Sidebar: What does internal linkage mean?

In C and C++, we have three kinds of linkage: External, Internal and No linkage. To define these, I’m going to quote from C++ 2011 Section 3.5 Paragraph 2:

A name is said to have linkage when it might denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope:

  • When a name has external linkage , the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.
  • When a name has internal linkage , the entity it denotes can be referred to by names from other scopes in the same translation unit.
  • When a name has no linkage , the entity it denotes cannot be referred to by names from other scopes.

C 2011 has similar language at Section 6.2.2 Paragraph 2:

In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.

So names that have internal linkage are only visible in the translation unit that they were found in.

Sidebar: Let’s include an example of how internal linkage works in practice:

Let’s create 2 c++ files. bar.cc will contain just a function with internal linkage:

static void bar() {}

We’ll also create main.cc, which will try to use that bar().

extern void bar();

int main() {
    bar();
}

If we compile this, our linker will complain. there is no function named bar that we can find from the main.cc translation unit. This is the expected behavior of internal linkage.

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)

Leave a Comment