This standard recommends the inclusion of diagnostic tests into your program using the assert()
macro or other mechanisms (see MSC11-A. Incorporate diagnostic tests using assertions). Static assertion is a new facility in the C++ 0X draft standard. This facility enables assertions to be made at compile time rather than runtime, providing meeting the following advantagesrequirements:
- All processing must be performed during compile time - no runtime cost in space or time is tolerable.
- Assertion failure must result in a meaningful and informative diagnostic error message.
- It can be used at file or block scope.
- Misuse does not result in silent malfunction but is diagnosed at compile time.
...
Code Block | ||
---|---|---|
| ||
struct timer { uint8_t MODE; uint32_t DATA; uint32_t COUNT; }; int mainfunc(void) { assert(offsetof(timer, DATA) == 4); } |
...
Code Block | ||
---|---|---|
| ||
struct timer { uint8_t MODE; uint32_t DATA; uint32_t COUNT; }; #if (offsetof(timer, DATA) != 4) #error "DATA must be at offset 4" #endif |
Using #error
directives allows for clear diagnostic messages. Because this approach evaluates assertions at compile time, there is no run-time penalty.
...
Code Block | ||
---|---|---|
| ||
#define JOIN(x, y) JOIN_AGAIN(x, y) #define JOIN_AGAIN(x, y) x ## y #define static_assert(e, s) \ typedef char JOIN(assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1] struct timer { uint8_t MODE; uint32_t DATA; uint32_t COUNT; }; static_assert(offsetof(struct timer, DATA) == 4, "offsetof(struct timer, DATA) == 4"); |
The static_assert()
macro accepts a constant expression e
, which is evaluated as the first operand to the conditional operator. If e
evaluates to nonzero, an array type with a dimension of 1 is defined; otherwise an array type with a dimension of -1 is defined. Because it is invalid to declare an array with a negative dimension, the resulting type definition will be flagged by the compiler. The name of the array is used to indicate the location of the failed assertion.
...