Anonymous Namespaces
- Rule ID:
anonymous_namespace- Severity:
high
Anonymous namespaces may seem like a convenient place for helper functions or constants in implementation files, avoiding linker conflicts. In a large library like Erbsland Core, however, they are almost always bad practice.
Why We Do Not Tolerate Anonymous Namespaces
Functions in anonymous namespaces are untestable because they expose no accessible API for granular unit testing.
Erbsland Core supports unity builds, where multiple implementation files are combined into a single compilation unit. Anonymous namespaces are merged as well, which can lead to unpredictable name conflicts.
Unacceptable Solutions
Only removing the anonymous namespace is no solution, because the helper or constant still exists, is still hidden in the implementation, and is still untestable.
Converting the anonymous namespace into a real namespace with a unique name is no solution, because this is only an anonymous namespace in disguise.
Correct Solutions for Common Problems
Small free helper functions:
Before writing a helper function, ask yourself:
Does this functionality already exist in the library? If so, use the existing implementation.
Does it operate on a library type? If the functionality is closely related to that type and could be useful elsewhere, extend the type’s API instead. Prefer
object.myAction()overmyAction(object).Is it specific to the implementation of a public API? If so, a private or private static member function is often the best choice.
Exceptions include:
Template-heavy implementations that would unnecessarily increase the include surface.
Platform-specific code.
Circular dependencies.
Otherwise, create a new compilation unit in an impl subdirectory with a separate hpp and optional cpp file.
Place the free functions in the erbsland::<domain>::impl namespace.
This is often preferable even to private helper methods because the functions remain independently unit-testable.
Implementation-only types (classes, enums, enum classes):
Never place implementation-only types in anonymous namespaces.
Instead, create a dedicated compilation unit in an impl subdirectory with a hpp and optional cpp file,
define the type there, and include it where needed.
Mechanical Detection
The scanner detects namespace { outside comments and literals.