<

Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x

Static assertions in C++

Published on
13,719 Points
7,119 Views
6 Endorsements
Last Modified:
evilrix
An expert in cross-platform ANSI C/C++ development, specialising in meta-template programming and low latency scalable architecture design.
Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their way to become runtime problems are harder to detect and may go unchecked until such time that the code reaches a customer. The later the defect is identified the more costly it is in terms of time and money.

A static assertion is similar to a runtime assertion, in so far as it allows the programmer to assert that an expression must be true, or an error message must be raised. The difference is that static assertions are triggered at compile time rather than runtime. How is this useful? Well, how about a situation where we've had to make assumptions about the capacity of a specific type, say int?

The C++ Standard makes no specific claims about how big an int will be other than it "has the natural size suggested by the architecture of the execution environment."

What does this actually mean? Well, in reality, it means the size of an int could be any size. The same is true of other types; a long must be as least as big as an int and an int at least s big as a short. Clearly, making an assumption about type size is non-portable and potentially dangerous, and should only be done in controlled cases, such as writing an OS kernel for a particular processor with a particular compiler. As soon as the programmer loses the ability to specify the compiler and the target architecture, type size assumptions go out the window. So, how does a static assertion help? Good question, let's see...

Wouldn't it be nice if we could assert our assumption about the size of a type at compile time so that if this assumption breaks, we are alerted immediately? For example, the code is built by a different compiler than the author used on a platform he did not anticipate. Enter static assertions. The trick is to turn to templates and, specifically, make use of the fact that a template variant, that is not instantiated, will not cause a compile time failure even if it contains erroneous code.

Create a template function that takes a bool template value parameter (not a function parameter). Within the function create a char array and use the value of the bool to determine the size. In the case where the bool template value is true, a char array of one element will be created. Since this will never be used the compiler should happily optimize this away. In the case where the bool template value is false, the compiler will try to generate a template function that creates a char array of zero elements. Since this is invalid C++, a compiler error will ensue. We can now use a simple macro to facilitate the use of this template and then use a sizeof() to assert the sizes of the types we are assuming. Of course, any compile time constant can be asserted with a static assert, this is just one example of usage.
template <bool B>
inline void STATIC_ASSERT_IMPL()
{
	// B will be true or false, which will implictly convert to 1 or 0
	char STATIC_ASSERT_FAILURE[B] = {0};
}
 
#define STATIC_ASSERT(B) STATIC_ASSERT_IMPL <B>()
 
int main()
{
	// On a Windows 32 bit platform with Visual Studio 2005 this will not fail
	STATIC_ASSERT(sizeof(int) == 4);
 
	// On a Windows 32 bit platform with Visual Studio 2005 this *will* fail
	STATIC_ASSERT(sizeof(int) == 3);
}

Open in new window

6
Comment
Author:evilrix
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 
LVL 40

Expert Comment

by:mrjoltcola
Great article. I just used this trick on a current project of mine where I use bitfields and read/write packed structures to/from disk, so I need to know in some cases that my assumptions are true, this saves me some trouble as I don't have to worry about a lot of ifdefs, I just set the assertions and forget about it.

mrjoltcola
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Join & Write a Comment

The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month