Pre C++11 , we had run time assertion function assert(). If assertion fails , a message will be written to console and abort() will be called, terminating the program execution at run time. As assert() works only when control passes over the assertion, there is a possibility that a failing run-time assertion may lay dormant, undetected for long period of time.
#include<iostream> #include<cassert> class A { int x; public: A(int a):x(a){} int getX(){ return x; } }; int main() { A a(17); assert(a.getX()<10); std::cout<< "Assertion a.getX()<10 pass"; return 0; }
Above program will compile fine, even though assert condition is false but we got the failure only at runtime.
Output:
assertion "a.getX()<10" failed: file "assert.cpp", line 16, function: int main()
Aborted (core dumped)
Therefore C++11 introduced Compile time Assertion functionality using static_assert(). As Compilation will fail, developer will be aware of the problematic portion of the code and track bugs early in development phase. Also For Example, if some functionality of code critically depends on size of int to be exactly 4 bytes, we can use static_assert like below
#include<iostream> class A { public: static const int b = 3; }; int main() { static_assert(A::b > 4, "A::bar is less than 4"); static_assert(sizeof(int) == 4,"size of integer is not 4 bytes"); }
static_assert can be also used to check whether class is default constructable or can be constructed with certain parameters or can be copied or is movable or assignable using trivial/non trivial constructors.
#include<iostream> class A { int x; public: A():x(0) { } A(int a):x(a) { } }; int main() { static_assert(std::is_constructible<A>::value, "Class is not constructible"); static_assert(std::is_trivially_constructible<A>::value," Class is not trivially constructible "); static_assert(std::is_constructible<A,char,int>::value, "Class is not constructible with char,int "); static_assert(std::is_trivially_copy_constructible<A>::value,"Class is not trivially copy constructible"); return 0; }
Output:
static_assert_constructors.cpp: In function ‘int main()’:
static_assert_constructors.cpp:20:9: error: static assertion failed: Class is not trivially construtible
static_assert(std::is_trivially_constructible<A>::value," Class is not trivially construtible ");
^
static_assert_constructors.cpp:21:5: error: static assertion failed: Class is not constructible with char,int
static_assert(std::is_constructible<A,char,int>::value, "Class is not constructible with char,int ");
Few Other standard values introduced in C++11, that you can use with static_assert are:
- std::is_move_assignable<T>::value,
- std::is_nothrow_copy_constructible<T>::value
- std::is_trivially_copyable<T>::value
- std::is_copy_assignable<T>::value
- std::is_default_constructible<T>::value
- std::is_assignable<T>::value