m |
m (typo fixed) |
||
Line 47: | Line 47: | ||
== Alternative solutions == | == Alternative solutions == | ||
− | The _Static_assert keyword was only added in C11, a number of alternative solutions were developed over the | + | The _Static_assert keyword was only added in C11, a number of alternative solutions were developed over the years to deliver a similar solution. The most common method is using an illegal-sized array to generate an error. For example: |
<source lang="c">#define COMPILE_TIME_ASSERTION(name, static_expr) \ | <source lang="c">#define COMPILE_TIME_ASSERTION(name, static_expr) \ |
Revision as of 09:57, 17 December 2013
The _Static_assert is a keyword added in the C11 standard version of the C Programming Language that provides a compile-time assertions mechanism to the language. The keyword was added as a better way of performing compile-time logic checking over previous existing solutions, primarily via the #error directive and negative array sizes.
Overview
Prior to the C11 standard the primary mean of producing a compile-time error message was via the #error directive which has been part of the language since C89 which causes the implementation to produce a diagnostic message that includes the message that followed it.
A common way of determining size of an int was to use some code along the following lines:
#if INT_MAX <= 65535
/* some code, 2 bytes */
#else
/* some code, 4 bytes */
#endif
The code above works for simple tasks. However, often a more complex task is required such as using the sizeof operator. Unfortunately, tokens such as 'sizeof' are not converted to source tokens until after the preprocessing translation stage at which point you can no longer use preprocessing directives.
For example:
/* wrong code, sizeof has no special meaning during the preprocessing stage */
#if sizeof(long) < 8
# error 'long' is expected to be at least 64-bits!
#endif
The _Static_assert was added to solve this issue by adding a compile-time assertion mechanism that takes place after the preprocessing translation stage.
_Static_assert(constant-expression, string-literal);
_Static_assert takes an integer constant expression. If the constant expression compares unequal to 0, the declaration has no effect. Otherwise it is assumed to produce a constraint violation and the implementation is required to produce a diagnostic message. The diagnostic message must include all the text of from the string-literal (with the exception of any characters that are not in the basic source character set).
Examples
It is sometimes desired to check the size of particular objects during compile time. The sizeof operator can be used with _Static_Assert, unlike in the preprocessing stage.
/* checking for the size of long */
_Static_assert(sizeof (long) == 8, "Code relies on 'long' being exactly 8 bytes");
/* checking that a function point size equals a void pointer size */
_Static_assert(sizeof (void(*)()) == sizeof (void*),
"Code requires function pointers and void pointers having the same size");
int main(void)
{
return 0;
}
Convenience macro
C11 defines a convenience macro static_assert in <assert.h> which expands to _Static_assert.
Alternative solutions
The _Static_assert keyword was only added in C11, a number of alternative solutions were developed over the years to deliver a similar solution. The most common method is using an illegal-sized array to generate an error. For example:
#define COMPILE_TIME_ASSERTION(name, static_expr) \
char static_assertion_##name[static_expr]
Which can be used as:
COMPILE_TIME_ASSERTION(int_size, sizeof (long) * CHAR_BIT >= 64);