Question

I've heard it asserted that the use of unnamed namespaces in C++ to define functions and ensure that they cannot be called from outside the compilation unit in which they are defined is not good in very large code environments because they cause the symbol table to grow unnecessarily large by including entries to these symbols in the automatically generated namespaces that the C++ compiler provides when unnamed.

namespace {
  // This function can only be accessed from hear to the end of 
  // any compilation unit that includes it.
  void functionPerhapsInsertedIntoSymbolTable() {
    return;
  }
}

This is perhaps given that the above is supposed to be the same as doing the following:

namespace randomlyGenerateNameHereNotCollidingWithAnyExistingNames {
  // This function can only be accessed from hear to the end of
  // any compilation unit that includes it.
  void functionPerhapsInsertedIntoSymbolTable() {
    return;
  }
}
using randomlyGenerateNameHereNotCollidingWithAnyExistingNames;

However, is it really that simple, is the compiler required to make a symbol table entry for symbols in the generated namespace name?

Instead, in such situations, I heard it suggested to use a static declaration:

// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
static void functionNotInsertedIntoSymbolTable() {
  return;
}

Is it true that using a static declaration before a function instead of placing it in an unnamed namespace has the same effect of making the function inaccessible outside the compilation unit in which it is defined? Is there any difference between these two approaches other than potentially not causing the symbol table to grow?

Is the issue with symbol table bloat due to unnamed namespaces just a bug in some implementations of C++ or is the compiler somehow required by the standard to create entries for such functions? If this bloat is considered a bug, are there known compilers for which this is not an issue?

Was it helpful?

Solution

Is it true that using a static declaration before a function instead of placing it in an unnamed namespace has the same effect of making the function inaccessible outside the compilation unit in which it is defined?

Yes.

Namespace-static was deprecated in C++03 in favour of unnamed namespaces, but in fact un-deprecated for C++11 when everybody realised that they are just the same thing and there was no purpose to the deprecation.

Is there any difference between these two approaches

No, not really. There may be some minor subtleties with name lookup due to the use of a namespace, but I can't think of any right now.

other than potentially not causing the symbol table to grow?

Since this is a language-lawyer question with no evident practical problem to solve, I am obliged to point out that the C++ language has no concept of a symbol table, and thus no indication of this effect.

It's also not going to have any noticeable effect until you have tens of thousands of unnamed namespaces; do you?

OTHER TIPS

The reason for the unnamed namespace and deprecation of namespace level static is the ill-fated export keyword.

Everything an exported template relies on has to be link-accessible at the points of instantiation, which are most likely in different source files. The unnamed namespace allowed the 'privatization' aspect of static while still preserving linkage for exported templates.

Now that export has been removed in C++2011, I'm pretty sure the external linkage requirement for the unnamed namespace has been removed, and it now behaves exactly like namespace level static. Someone more familiar with the standard can confirm/refute this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top