The Basics
When implementing user-defined types or functions, there are assumptions that the developer must make about the input provided to the system or about the state of the system when the code is executed.These assumptions fall into a few categories:
- Assumptions that can be verified at compile-time
- Assumptions that can be verified at run-time
- Assumptions that cannot be verified
- Unrecognized assumptions
Developers should prefer to verify as many assumptions as possible and to perform this verification as early in the development process as possible.
The C++ standard's run-time assertion capabilities are provided by the assert macro (from the <cassert> header). It will turn into a no-op if the NDEBUG macro is defined (i.e. in "release" builds) when you include the header file. You can use it like this.
#include <cassert>
const char * dayOfWeek (unsigned short which)
{
assert(("There are only 7 days in a week", which <= 6));
const char* days[] = { "Sunday", "Monday",
"Tuesday", "Wednesday",
"Thursday", "Friday",
"Saturday" };
return days[which];
}
As of 2011, the C++ standard now includes a compile-time assertion facility that is built into the language, static_assert. Unlike assert, static_assert never generates any code in the resulting binary, and thus cannot not be disabled. Since it is a language keyword, it requires no header file. It takes the following form.
static_assert ( constant-expression , string-literal ) ;
constant-expression must be convertible (at compile-time) to a bool. If the value of constant-expression evaluates to true, then there are no side effects, otherwise the compiler will produce an error message that includes the value of string-literal.
static_assert(sizeof(char) <= sizeof(short), "Your compiler is no good."); should have no effect (unless you have a really REALLY bad compiler). If you were to invert that comparison such that the assertion looked like static_assert(sizeof(char) > sizeof(short), "Your compiler is bad");, then you would get an error similar to this.
error: static assertion failed: Your compiler is bad
Those are the basics!
Availability
Unlike many other C++11 features, most shipping C++ compilers already implement static_assert, making it a great candidate for adoption into your coding practice.
Upcoming topics
I hope to get entries up for the rest of the series fairly soon. Check back later for the rest of the topics in the series.
- Monitoring external types for changes
- Better template error messages
- Future-proofing against buffer overflows
- Future-proofing against unexpected overload resolution
- Protecting against undesirable memory growth
- Learn about the language and your compiler
- TBD?
- Possible futures for compile-time assertions