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