- References
- Function Overloading
- Default Function Arguments
- Inline Function
- Dynamic Memory Allocation
- Placement New
- nullptr
- Namespaces
- Type Aliases
- Enum classes
- constexpr
- static_assert
- mutable Keyword
- auto Keyword
- Smart Pointers
- Basics of Classes
- Constructors
- Destructors
- Operator Overloading
- Copy Semantics
- Move Semantics
- Composition, RAII & Ownership
- Inheritance
- Polymorphism
- Abstraction
- Encapsulation
- Template
- Static Memory
- Friend Function
- this Pointer
- Function Pointer
- Lambdas and Callback Management
- Union
Namespaces (Scope Containers)

In C, to avoid naming conflicts, we rely on long prefixes (e.g., HAL_UART_Init, HAL_SPI_Init).
In C++, a Namespace is a declarative region that provides a scope to identifiers (names of types, functions, variables, etc.). It allows you to group related code together and reuse common names like Init, Start, or Status without collision.
Syntax & Usage
1. Basic Declaration
Wrap your declarations in a namespace block.
namespace UART {
int baud_rate;
void init() { /* ... */ }
}
namespace SPI {
int baud_rate; // No conflict with UART::baud_rate
void init() { /* ... */ } // No conflict with UART::init
}2. Accessing Members
Use the Scope Resolution Operator (::).
UART::init();
SPI::init();
UART::baud_rate = 9600;3. The using Directive
You can import a namespace into the current scope to avoid typing the prefix repeatedly.
Warning: Use with caution (see Pitfalls).
using namespace UART;
init(); // Calls UART::init() implicitlyScope Visualization
Namespaces create logical "folders" for your code symbols.
| C Approach (Prefixes) | C++ Approach (Namespaces) |
|---|---|
void LCD_Display_Init(); | namespace LCD { void Init(); } |
void LCD_Display_Clear(); | namespace LCD { void Clear(); } |
void Motor_Control_Init(); | namespace Motor { void Init(); } |
Call: LCD_Display_Init(); | Call: LCD::Init(); |
Relevance in Embedded/Firmware
1. Clean Driver APIs
Embedded systems have many peripherals (I2C, SPI, UART, CAN) that perform identical actions: read, write, init, reset.
Namespaces allow you to use these intuitive names for every driver without C-style prefix hell.
CAN::send(msg)WiFi::send(packet)Log::send(string)
2. Board Support Packages (BSP)
You can switch hardware configurations easily using namespace aliases.
// In config.h
namespace SensorBus = I2C1; // Alias
// In main.cpp
SensorBus::read(); // Reads from I2C1. Change alias to switch to SPI.3. Avoiding Library Collisions
If you use two external libraries (e.g., a "Motor Library" and a "Display Library") and both define a struct named Point or Color, C compilation fails.
If they are wrapped in namespaces (MotorLib::Point, GuiLib::Point), they coexist peacefully.
Common Pitfalls (Practical Tips)
| Pitfall | Details |
|---|---|
❌ using namespace in Headers | Never write using namespace in a header file (.h). It forces that namespace on every single file that includes the header, defeating the purpose of namespaces and causing random conflicts. |
| ❌ Pollution | Putting everything into one massive namespace doesn't help. Keep namespaces granular (e.g., Drivers::GPIO, Drivers::UART). |
| ✅ Anonymous Namespace | namespace { int internal_var; } in a .cpp file creates a variable that is private to that file (like C static global). This is the preferred C++ way to hide helper functions. |
| ✅ Namespace Aliases | Use aliases to shorten long nested names: |
Concept understood? Let's apply and learn for real