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.
Renaming an anonymous namespace while leaving its helpers hidden in a
cppfile does not provide an accessible header interface for unit tests.
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 logical unit below an impl directory with a separate hpp and optional cpp file.
Place the free functions in erbsland::<domain>::impl or a named helper namespace beneath it.
The helper namespace may share its parent’s directory when it owns one logical unit; follow Guidelines for File Structures for
directory layout.
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 logical unit below an impl directory 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.