]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man/man3/static_assert.3
man/, share/mk/: Move man*/ to man/
[thirdparty/man-pages.git] / man / man3 / static_assert.3
CommitLineData
4a96ff90
AC
1.\" Copyright (c) 2022 by Alejandro Colomar <alx@kernel.org>
2.\"
3.\" SPDX-License-Identifier: Linux-man-pages-copyleft
4.\"
5.TH static_assert 3 (date) "Linux man-pages (unreleased)"
6.SH NAME
7static_assert, _Static_assert \- fail compilation if assertion is false
8.SH LIBRARY
9Standard C library
10.RI ( libc )
11.SH SYNOPSIS
12.nf
13.B #include <assert.h>
c6d039a3 14.P
4a96ff90 15.BI "void static_assert(scalar " constant-expression ", const char *" msg );
c6d039a3 16.P
4a96ff90
AC
17/* Since C23: */
18.BI "void static_assert(scalar " constant-expression );
19.fi
20.SH DESCRIPTION
21This macro is similar to
22.BR \%assert (3),
23but it works at compile time,
24generating a compilation error (with an optional message)
25when the input is false (i.e., compares equal to zero).
c6d039a3 26.P
4a96ff90
AC
27If the input is nonzero,
28no code is emitted.
c6d039a3 29.P
4a96ff90
AC
30.I msg
31must be a string literal.
32Since C23, this argument is optional.
c6d039a3 33.P
4a96ff90
AC
34There's a keyword,
35.BR \%_Static_assert (),
36that behaves identically,
37and can be used without including
38.IR <assert.h> .
39.SH RETURN VALUE
40No value is returned.
41.SH VERSIONS
42In C11,
43the second argument
44.RI ( msg )
45was mandatory;
46since C23,
47it can be omitted.
48.SH STANDARDS
49C11 and later.
50.SH EXAMPLES
51.BR static_assert ()
52can't be used in some places,
53like for example at global scope.
54For that,
55a macro
56.BR \%must_be ()
57can be written in terms of
58.BR \%static_assert ().
59The following program uses the macro to get the size of an array safely.
c6d039a3 60.P
4a96ff90
AC
61.in +4n
62.\" SRC BEGIN (must_be.c)
63.EX
64#include <assert.h>
65#include <stddef.h>
66#include <stdint.h>
67#include <stdio.h>
68#include <stdlib.h>
69#include <string.h>
fe5dba13 70\&
4a96ff90
AC
71/*
72 * This macro behaves like static_assert(), failing to
73 * compile if its argument is not true. However, it always
74 * returns 0, which allows using it everywhere an expression
75 * can be used.
76 */
77#define must_be(e) \e
78( \e
79 0 * (int) sizeof( \e
80 struct { \e
81 static_assert(e); \e
82 int ISO_C_forbids_a_struct_with_no_members; \e
83 } \e
84 ) \e
85)
fe5dba13 86\&
4a96ff90
AC
87#define is_same_type(a, b) \e
88 __builtin_types_compatible_p(typeof(a), typeof(b))
fe5dba13 89\&
4a96ff90
AC
90#define is_array(arr) (!is_same_type((arr), &*(arr)))
91#define must_be_array(arr) must_be(is_array(arr))
fe5dba13 92\&
4a96ff90
AC
93#define sizeof_array(arr) (sizeof(arr) + must_be_array(arr))
94#define nitems(arr) (sizeof((arr)) / sizeof((arr)[0]) \e
95 + must_be_array(arr))
fe5dba13 96\&
4a96ff90
AC
97int foo[10];
98int8_t bar[sizeof_array(foo)];
fe5dba13 99\&
4a96ff90
AC
100int
101main(void)
102{
103 for (size_t i = 0; i < nitems(foo); i++) {
104 foo[i] = i;
105 }
fe5dba13 106\&
4a96ff90 107 memcpy(bar, foo, sizeof_array(bar));
fe5dba13 108\&
4a96ff90
AC
109 for (size_t i = 0; i < nitems(bar); i++) {
110 printf("%d,", bar[i]);
111 }
fe5dba13 112\&
4a96ff90
AC
113 exit(EXIT_SUCCESS);
114}
115.EE
208d6211 116.\" SRC END
4a96ff90
AC
117.in
118.SH SEE ALSO
119.BR assert (3)