Static assert is a compiler mechanism for generating errors at compile time if an expression (condition) is not satisfied. This functionality was added starting with C++11 to facilitate template programming and improve code quality.
Background.
Before static_assert, programmers used tricks like structures with a negative array size (e.g., char arr[condition?1:-1];), which were less readable and less convenient for error diagnosis. This created a need for explicit declarations of compile-time errors with meaningful messages.
Problem.
In template programming, there is often a need for early diagnostics (e.g., preventing the creation of an object with an inappropriate type or parameter). Without static checking, these errors would only appear during the compilation of the final code (sometimes as sudden and poorly explained errors).
Solution.
The static_assert keyword takes a boolean expression and a message string. If the expression is false, compilation will fail with the message output.
Example code:
static_assert(sizeof(int) >= 4, "int must be at least 4 bytes"); template<typename T> void foo(const T& obj) { static_assert(std::is_copy_constructible<T>::value, "T must be copy-constructible"); }
Key features:
Can static_assert be used without a second argument?
Yes, starting from C++17, the second argument is optional:
static_assert(sizeof(double) == 8); // message will be default
Are static_assert expressions executed if the condition depends on template parameters, but the template is not instantiated?
No, static_assert only triggers if it reaches the instantiation point, allowing checks to be applied only to instantiated templates.
Can runtime expressions be used inside static_assert?
No, the expression must be evaluable at compile time (constexpr). If the expression is not constexpr, a compilation error occurs.
In the code, static_assert was used with an expression evaluated only at runtime (e.g., file size with input reading), which resulted in an unclear compilation error throughout the system.
Pros:
Cons:
It is required to ensure that the Matrix template can only be instantiated with Plain Old Data (POD) types, excluding complex structures.
template<typename T> class Matrix { static_assert(std::is_pod<T>::value, "Matrix can be instantiated only for POD types"); // ... };
Pros:
Cons: