xref: /freebsd/share/man/man7/sizeof.7 (revision 9768746ba83efa02837c5b9c66348db6e900208f)
1.\"
2.\" Copyright (C) 2022 Jan Schaumann <jschauma@netmeister.org>.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.Dd December 12, 2022
26.Dt sizeof 7
27.Os
28.Sh NAME
29.Nm sizeof
30operator
31.Nd yield the storage size of the given operand
32.Sh SYNTAX
33.Nm Vt ( type )
34.br
35.Nm Vt expression
36.Sh DESCRIPTION
37The
38.Nm
39operator yields the size of its operand.
40The
41.Nm
42operator cannot be applied to incomplete types and expressions
43with incomplete types (e.g.
44.Vt void ,
45or forward-defined
46.Vt struct foo ),
47and function types.
48.Pp
49The size of primitive (non-derived) data types in C may differ
50across hardware platforms and implementations.
51They are defined by corresponding Application Binary Interface (ABI)
52specifications, see
53.Xr arch 7
54for details about ABI used by
55.Fx .
56It may be necessary or useful for a program to be able
57to determine the storage size of a data type or object
58to account for the platform specifics.
59.Pp
60The unary
61.Nm
62operator yields the storage size of an expression or
63data type in
64.Em char sized units
65(C language bytes).
66As a result,
67.Ql sizeof(char)
68is always guaranteed to be 1.
69(The number of bits per
70.Vt char
71is given by the
72.Dv CHAR_BIT
73definition in the
74.In limits.h
75header; many systems also provide the "number of bits
76per byte" definition as
77.Dv NBBY
78in the
79.In sys/param.h
80header.)
81.Sh EXAMPLES
82Different platforms may use different data models.
83For example, systems on which integers, longs, and
84pointers are using 32 bits (e.g., i386) are referred
85to as using the "ILP32" data model, systems using
8664 bit longs and pointers (e.g., amd64 / x86_64)
87as the "LP64" data model.
88.Pp
89The following examples illustrate the possible results
90of calling
91.Nm
92on an ILP32 vs. an LP64 system:
93.Pp
94When applied to a simple variable or data type,
95.Nm
96returns the storage size of the data type of the object:
97.Bl -column -offset indent \
98    ".Li sizeof(struct flex)" ".Sy Result (ILP32)" ".Sy Result (LP64)"
99.It Sy Object or type \
100 Ta Sy Result (ILP32) \
101 Ta Sy Result (LP64)
102.It Li sizeof(char) \
103 Ta 1 \
104 Ta 1
105.It Li sizeof(int) \
106 Ta 4 \
107 Ta 4
108.It Li sizeof(long) \
109 Ta 4 \
110 Ta 8
111.It Li sizeof(float) \
112 Ta 4 \
113 Ta 4
114.It Li sizeof(double) \
115 Ta 8 \
116 Ta 8
117.It Li sizeof(char *) \
118 Ta 4 \
119 Ta 8
120.El
121.Pp
122For initialized data or uninitialized arrays of a
123fixed size known at compile time,
124.Nm
125will return the correct storage size:
126.Bd -literal -offset indent
127#define DATA "1234567890"
128char buf1[] = "abc";
129char buf2[1024];
130char buf3[1024] = { 'a', 'b', 'c' };
131.Ed
132.Bl -column -offset indent \
133    ".Li sizeof(struct flex)" ".Sy Result"
134.It Sy Object or type \
135 Ta Sy Result
136.It Li sizeof(DATA) \
137 Ta 11
138.It Li sizeof(buf1) \
139 Ta 4
140.It Li sizeof(buf2) \
141 Ta 1024
142.It Li sizeof(buf3) \
143 Ta 1024
144.El
145.Pp
146The examples above are the same for ILP32 and LP64
147platforms, as they are based on character units.
148.Pp
149When applied to a struct or union,
150.Nm
151returns the total number of bytes in the object,
152including any internal or trailing padding used to
153align the object in memory.
154This result may thus be larger than if the storage
155size of each individual member had been added:
156.Bd -literal -offset indent
157struct s1 {
158        char c;
159};
160
161struct s2 {
162        char *s;
163        int i;
164};
165
166struct s3 {
167        char *s;
168        int i;
169        int j;
170};
171
172struct s4 {
173	int i;
174	uint64_t i64;
175};
176
177struct s5 {
178        struct s1 a;
179        struct s2 b;
180        struct s3 c;
181        struct s4 d;
182};
183.Ed
184.Bl -column -offset indent \
185    ".Li sizeof(struct flex)" ".Sy Result (ILP32)  " ".Sy Result (LP64)"
186.It Sy Object or type \
187 Ta Sy Result (ILP32) \
188 Ta Sy Result (LP64)
189.It Li sizeof(struct s1) \
190 Ta 1 \
191 Ta 1
192.It Li sizeof(struct s2) \
193 Ta 8 \
194 Ta 16
195.It Li sizeof(struct s3) \
196 Ta 12 \
197 Ta 16
198.It Li sizeof(struct s4) \
199 Ta 12 \
200 Ta 16
201.It Li sizeof(struct s5) \
202 Ta 36  \
203 Ta 56
204.El
205.Pp
206When applied to a struct containing a flexible array
207member,
208.Nm
209returns the size of the struct
210.Em without
211the array, although again possibly including any
212padding the compiler deemed appropriate:
213.Bd -literal -offset indent
214struct flex {
215        char c;
216        long b;
217        char array[];
218}
219.Ed
220.Bl -column -offset indent \
221    ".Li sizeof(struct flex)" ".Sy Result (ILP32)  " ".Sy Result (LP64)"
222.It Sy Object or type \
223 Ta Sy Result (ILP32) \
224 Ta Sy Result (LP64)
225.It Li sizeof(struct flex) \
226 Ta 8 \
227 Ta 16
228.El
229.Pp
230One of the more common uses of the
231.Nm
232operator is to determine the correct amount of memory
233to allocate:
234.Bd -literal -offset indent
235int *nums = calloc(512, sizeof(int));
236.Ed
237.Pp
238The
239.Nm
240operator can be used to calculate the number of
241elements in an array by dividing the size of the array
242by the size of one of its elements:
243.Bd -literal -offset indent
244int nums[] = { 1, 2, 3, 4, 5 };
245const int howmany = sizeof(nums) / sizeof(nums[0]);
246.Ed
247.Pp
248Many systems provide this shortcut as the macro
249.Dv ntimes()
250via the
251.In sys/param.h
252header file.
253.Sh RESULT
254The result of the
255.Nm
256operator is an unsigned integer type, defined in the
257.Dv stddef.h
258header as a
259.Vt size_t .
260.Sh NOTES
261It is a common mistake to apply
262.Nm
263to a dynamically allocated array:
264.Bd -literal -offset indent
265char *buf;
266if ((buf = malloc(BUFSIZ)) == NULL) {
267        perror("malloc");
268}
269/* Warning: wrong! */
270(void)strncat(buf, input, sizeof(buf) - 1);
271.Ed
272.Pp
273In that case, the operator will return the storage
274size of the pointer (
275.Ql sizeof(char *)
276), not the
277allocated memory.
278.Pp
279.Nm
280determines the
281.Ev size
282of the result of the expression given, but
283.Em does not
284evaluate the expression:
285.Bd -literal -offset indent
286int a = 42;
287printf("%ld - %d\\n", sizeof(a = 10), a); /* Result: "4 - 42" */
288.Ed
289.Pp
290Since it is evaluated by the compiler and not the
291preprocessor, the
292.Nm
293operator cannot be used in a preprocessor expression.
294.Sh SEE ALSO
295.Xr arch 7 ,
296.Xr operator 7
297.Sh STANDARDS
298The
299.Nm
300operator conforms to
301.St -ansiC .
302.Pp
303Handling of flexible array members in structures
304conforms to
305.St -isoC-99 .
306.Sh AUTHORS
307This manual page was written by
308.An Jan Schaumann Aq Mt jschauma@netmeister.org .
309