]>
Commit | Line | Data |
---|---|---|
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 | |
7 | static_assert, _Static_assert \- fail compilation if assertion is false | |
8 | .SH LIBRARY | |
9 | Standard 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 | |
21 | This macro is similar to | |
22 | .BR \%assert (3), | |
23 | but it works at compile time, | |
24 | generating a compilation error (with an optional message) | |
25 | when the input is false (i.e., compares equal to zero). | |
c6d039a3 | 26 | .P |
4a96ff90 AC |
27 | If the input is nonzero, |
28 | no code is emitted. | |
c6d039a3 | 29 | .P |
4a96ff90 AC |
30 | .I msg |
31 | must be a string literal. | |
32 | Since C23, this argument is optional. | |
c6d039a3 | 33 | .P |
4a96ff90 AC |
34 | There's a keyword, |
35 | .BR \%_Static_assert (), | |
36 | that behaves identically, | |
37 | and can be used without including | |
38 | .IR <assert.h> . | |
39 | .SH RETURN VALUE | |
40 | No value is returned. | |
41 | .SH VERSIONS | |
42 | In C11, | |
43 | the second argument | |
44 | .RI ( msg ) | |
45 | was mandatory; | |
46 | since C23, | |
47 | it can be omitted. | |
48 | .SH STANDARDS | |
49 | C11 and later. | |
50 | .SH EXAMPLES | |
51 | .BR static_assert () | |
52 | can't be used in some places, | |
53 | like for example at global scope. | |
54 | For that, | |
55 | a macro | |
56 | .BR \%must_be () | |
57 | can be written in terms of | |
58 | .BR \%static_assert (). | |
59 | The 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 |
97 | int foo[10]; |
98 | int8_t bar[sizeof_array(foo)]; | |
fe5dba13 | 99 | \& |
4a96ff90 AC |
100 | int |
101 | main(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) |