# static_assert

## NAME



           static_assert, _Static_assert - fail compilation if assertion is
           false
    


## LIBRARY



           Standard C library (_libc_)
    


## SYNOPSIS



           **#include <assert.h>**
    
           **void static_assert(bool** _constant-expression_**, const char ***_msg_**);**
    
           /* Since C23: */
           **void static_assert(bool** _constant-expression_**);**
    


## DESCRIPTION



           This macro is similar to assert(3), but it works at compile time,
           generating a compilation error (with an optional message) when the
           input is false (i.e., compares equal to zero).
    
           If the input is nonzero, no code is emitted.
    
           _msg_ must be a string literal.  Since C23, this argument is
           optional.
    
           There's a keyword, **_Static_assert**(), that behaves identically, and
           can be used without including _< assert.h>_.
    


## RETURN VALUE



           No value is returned.
    


## VERSIONS



           In C11, the second argument (_msg_) was mandatory; since C23, it can
           be omitted.
    


## STANDARDS



           C11 and later.
    


## EXAMPLES



           **static_assert**() can't be used in some places, like for example at
           global scope.  For that, a macro **must_be**() can be written in terms
           of **static_assert**().  The following program uses the macro to get
           the size of an array safely.
    
               #include <assert.h>
               #include <stdint.h>
               #include <stdio.h>
               #include <stdlib.h>
               #include <string.h>
    
               /*
                * This macro behaves like static_assert(), failing to
                * compile if its argument is not true.  However, it always
                * returns 0, which allows using it everywhere an expression
                * can be used.
                */
               #define must_be(e)                                        \
               (                                                         \
                   0 * (int) sizeof(                                     \
                       struct {                                          \
                           static_assert(e);                             \
                           int  ISO_C_forbids_a_struct_with_no_members;  \
                       }                                                 \
                   )                                                     \
               )
    
               #define is_same_type(a, b)  \
                   __builtin_types_compatible_p(typeof(a), typeof(b))
    
               #define is_array(arr)       (!is_same_type((arr), &*(arr)))
               #define must_be_array(arr)  must_be(is_array(arr))
    
               #define sizeof_array(arr)   (sizeof(arr) + must_be_array(arr))
               #define nitems(arr)         (sizeof((arr)) / sizeof((arr)[0]) \
                                            + must_be_array(arr))
    
               int     foo[10];
               int8_t  bar[sizeof_array(foo)];
    
               int
               main(void)
               {
                   for (size_t i = 0; i < nitems(foo); i++) {
                       foo[i] = i;
                   }
    
                   memcpy(bar, foo, sizeof_array(bar));
    
                   for (size_t i = 0; i < nitems(bar); i++) {
                       printf("%d,", bar[i]);
                   }
    
                   exit(EXIT_SUCCESS);
               }
    


* * *