SimplifyC++ Article
12 Modern C++ and Rust Programming – A Comparative Educational Guide from Concepts to Applications
#12 Modern C++ and Rust Programming – A Comparative Educational Guide from Concepts to Applications
Constants, Mutability, and Shadowing
Understanding how constants, mutability, and shadowing operate in C++ and Rust is fundamental for writing clear, efficient, and safe programs. Both languages provide mechanisms to control variable mutability and lifetime, but they differ significantly in their design philosophies and enforcement.
Constants
C++
Definition: In C++, constants are variables whose value cannot be modified after initialization. The keyword
constis used to declare constants.const int MAX_SIZE = 100;Characteristics:
constvariables must be initialized at the time of declaration.The compiler enforces that attempts to modify a
constvariable result in a compilation error.constexpr(introduced in C++11 and expanded in later standards) denotes values or functions that can be evaluated at compile time, allowing for better optimization (ISO C++20 Standard, cppreference on constexpr).constexprvariables are implicitlyconst, but with the added guarantee of compile-time evaluation.
Example:
constexpr double PI = 3.14159;References: https://en.cppreference.com/w/cpp/language/const https://en.cppreference.com/w/cpp/language/constexpr
Rust
Definition: Rust provides two main ways to define immutable data:
constdefines a constant value that is always immutable and must be known at compile time.letbindings are immutable by default unless declared withmut.
Characteristics:
constvalues in Rust must be explicitly typed and are evaluated at compile time. They are globally available and cannot be changed at runtime.letvariables are immutable unless prefixed withmut. This design enforces safety and intentional mutability (Rust Reference, Rust Book).
Examples:
const MAX_SIZE: u32 = 100;let x = 5; // immutablelet mut y = 10; // mutableReferences: https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html https://doc.rust-lang.org/reference/items/constant-items.html
Mutability
C++
By default, variables in C++ are mutable unless declared with
const.Mutable variables can be reassigned and modified freely.
C++ does not enforce immutability beyond the
constqualifier, andconst_castcan override constness, which can lead to undefined behavior if misused (cppreference).Example:
int x = 10; // mutablex = 20; // allowedconst int y = 30;// y = 40; // compilation errorReferences: https://en.cppreference.com/w/cpp/language/cv
Rust
In Rust, immutability is the default for all variables, and explicit
mutis required to declare a mutable variable. This design choice is fundamental to Rust’s safety guarantees, reducing unintended side-effects (Rust Book).Mutability applies to the binding itself, not the data. To mutate data behind a reference, Rust uses special types like
CellandRefCell(Rust official docs).Example:
let x = 5; // immutable by defaultlet mut y = 10; // mutable variabley = 15; // allowedReferences: https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html https://doc.rust-lang.org/std/cell/
Shadowing
Shadowing refers to declaring a new variable with the same name as a previous variable in the same or inner scope, effectively "hiding" the earlier variable.
C++
C++ does not support variable shadowing within the same scope. Shadowing may occur in nested scopes (e.g., inside blocks or functions), but it is generally discouraged due to potential confusion and errors (ISO C++ Standard).
Shadowing in C++ often involves hiding class member variables or global variables using local variable names, but the practice can lead to bugs and is often avoided with explicit naming conventions.
Example:
int x = 5;{int x = 10; // shadows outer x within this blockstd::cout << x; // prints 10}std::cout << x; // prints 5References: https://en.cppreference.com/w/cpp/language/scope
Rust
Rust allows and encourages shadowing by re-declaring variables with the same name using
let. This enables changing the type or mutability of a variable in a new scope without needing to create a new name, improving code clarity and safety (Rust Book).Shadowing allows immutable bindings to be “re-bound” as mutable or vice versa.
Example:
let x = 5;let x = x + 1; // shadows previous x, x is now 6let x = "hello"; // shadows again with a different typeReferences: https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing
Summary of Differences
| Feature | C++ | Rust |
|---|---|---|
| Constants | const and constexpr for compile-time constants | const for compile-time constants; let is immutable by default |
| Mutability | Mutable by default; const for immutability; const_cast allows override (unsafe) | Immutable by default; explicit mut required; no unsafe mutability override |
| Shadowing | Limited to nested scopes; discouraged | Encouraged; allows rebinding and type changes |
| Compile-time evaluation | Via constexpr from C++11 onwards | Via const and const fn (const functions) |
References
ISO C++ Standard and cppreference on
constandconstexprhttps://isocpp.org/std/the-standard https://en.cppreference.com/w/cpp/language/const https://en.cppreference.com/w/cpp/language/constexprRust Book: Variables and Mutability https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html
Rust Reference: Constants https://doc.rust-lang.org/reference/items/constant-items.html
C++ cv-qualifiers (const/volatile) https://en.cppreference.com/w/cpp/language/cv
Rust std::cell for interior mutability https://doc.rust-lang.org/std/cell/
C++ Scope and Variable Shadowing https://en.cppreference.com/w/cpp/language/scope
What did you think?
Sign in to react or comment.
Comments
0No comments yet.