In this article, we will discuss the static_assert in C++ with its syntax, parameters, and examples.
What is the static_assert?
The static_assert is a built-in feature in C++. It allows us to assert the statements during compile time. It is introduced in the C++11 version. This feature contains two main fields, conditions and messages . The condition should be a constant expression, and the message should be literal. This feature is mainly used to prevent potential errors from reaching runtime and make code more robust and clearer.
Syntax:
It has the following syntax:
static_assert(constant_expression, string_literal);
Parameters:
- The constant expression will give the constant Boolean value at compile time.
- String_literal is an error message that must be displayed when the constant expression is evaluated as false. Sometimes, the programmer does not give the message or the string literal. In that case, a default message is displayed.
- Static_assert will ensure that the condition is met only at compile time, not during the program's execution. However, the runtime assertions are used for debugging to catch unexpected conditions during execution.
Example:
Let us take a program to illustrate the static_assert method in C++.
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T>
void printSize() {
static_assert(sizeof(T) >= 4, "Size of type must be at least 4 bytes");
cout << "Size of type: " << sizeof(T) << " bytes" << endl;
}
int main() {
printSize<int>(); // This will work
printSize<short>(); // This will fail
return 0;
}
Output:
Explanation:
- In this example, the program has a function template named printSize , which is used to print the size of a given type. So here, we used the assert feature so that if the size of the type is less than 4 bytes, the error message is displayed in the console.
- There are many situations where we use the static_assert Some of them are checking constant expressions, checking the type sizes, validating configuration parameters, checking Enum values, validating template parameters, and validating compile-time computations, which are also used to ensure API compatibility.
- Before introducing this feature, other techniques are used to achieve a similar functionality for compile-time assertions. Some of them:
- The #error directive will stop the program when a particular condition is met. Using Enumerations to trigger a compilation error when the condition wasn't met.
- Situations where the static_assert feature is commonly used in programming.
Checking constant expressions:
Let us take a program to demonstrate the usage of the statc_assert function for checking constant expressions in C++.
#include <iostream>
using namespace std;
constexpr int MAX_SIZE = 100;
static_assert(MAX_SIZE > 0, "MAX_SIZE must be greater than zero");
int main() {
cout << "MAX_SIZE: " << MAX_SIZE << endl;
return 0;
}
Output:
Explanation:
In this program, a constexpr variable is defined and given the value of 100. After that, the assert will check whether the MAXSIZE is greater than 0. If the condition fails, errors are displayed, saying the MAXSIZe must be greater than zero.
Validation the configuration parameters:
Let us take a sample program to illustrate the usage of the feature in validating configuration parameters.
#include <iostream>
using namespace std;
constexpr int BUFFER_SIZE = 3000;
static_assert(BUFFER_SIZE >= 512 && BUFFER_SIZE <= 2048, "BUFFER_SIZE must be between 512 and 2048");
int main() {
cout << "BUFFER_SIZE: " << BUFFER_SIZE << endl;
return 0;
}
Output:
Explanation:
In the program, a variable BUFFERSIZE is initialized to 3000 . After that, the assert will check whether the BUFFERSIZE is within the range of 512 and 1048 . If the BUFFER_SIZE is not in that range, it will give the error message.
Validating the compile time computations:
Let us take an example to demonstrate the usage of the static_assert in validating the compile time computations:
#include <iostream>
using namespace std;
constexpr int Compute(int x) {
return x * 2;
}
static_assert(Compute(5) == 10, "Invalid computation result");
int main() {
cout << "Result of computation: " << Compute(5) << endl;
return 0;
}
Output:
Explanation:
This program illustrates the compile-time computations. It is used for compile-time verification of compute's correctness with its usage.
To verify size compatibility
Let us take an example to verify size compatibility using the static_assert method in C++.
#include <iostream>
using namespace std;
struct Point {
int x, y;
};
static_assert(sizeof(Point) == 8, "Point struct does not have expected size");
int main() {
cout << "Size of Point struct: " << sizeof(Point) << " bytes" << endl;
return 0;
}
Output:
Explanation:
Here, the static_assert feature is used to check whether the size of the given struct is 8 bytes or not. If it is 8 bytes, it compiles without any errors, and the size of the point struct is displayed; otherwise, it prints the message that the point struct does not have the expected size.
Disabling the code for unsupported feature:
Let us take a sample program to disable the code for unsupported feature in C++.
#include <iostream>
using namespace std;
#ifdef NO_FEATURE
static_assert(0, "This code section is not supported");
#endif
int main() {
cout << "Code section is supported!" << endl;
return 0;
}
Output:
Using feature without the string_literal
Let us take an example to demonstrate the static_assert function without using the message in C++.
#include <iostream>
using namespace std;
struct Point {
long x, y;
};
static_assert(sizeof(Point) == 16, "Point should be 16 bytes");
int main() {
cout << "Size of Point struct: " << sizeof(Point) << " bytes" << endl;
return 0;
}
Output: