System Grab Bag

View all man pages from Linux (or from all projects)

Name

static_assert, _Static_assert - fail compilation if assertion is false

Library

Standard C library ( libc )

Synopsis

#include <assert.h> 
void static_assert(scalar " constant-expression ", const char * msg );
/* Since C23: */ void static_assert(scalar 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 <stddef.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)                                        \e
(                                                         \e
    0 * (int) sizeof(                                     \e
        struct {                                          \e
            static_assert(e);                             \e
            int  ISO_C_forbids_a_struct_with_no_members;  \e
        }                                                 \e
    )                                                     \e
)

#define is_same_type(a, b)  \e
    __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]) \e
                             + 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);
}

See Also

  1. assert(3)