Changeset View
Standalone View
sizeof.7
.\" | |||||||||||||
.\" Copyright (C) 2022 Jan Schaumann <jschauma@netmeister.org>. | |||||||||||||
.\" All rights reserved. | |||||||||||||
.\" | |||||||||||||
.\" Redistribution and use in source and binary forms, with or without | |||||||||||||
.\" modification, are permitted provided that the following conditions | |||||||||||||
.\" are met: | |||||||||||||
.\" 1. Redistributions of source code must retain the above copyright | |||||||||||||
.\" notice, this list of conditions and the following disclaimer. | |||||||||||||
.\" 2. Redistributions in binary form must reproduce the above copyright | |||||||||||||
.\" notice, this list of conditions and the following disclaimer in the | |||||||||||||
.\" documentation and/or other materials provided with the distribution. | |||||||||||||
.\" | |||||||||||||
.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||||||||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||||||||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||||||||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE | |||||||||||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||||||||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||||||||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||||||||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||||||||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||||||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||||||||||
.\" SUCH DAMAGE. | |||||||||||||
.\" | |||||||||||||
.Dd December 12, 2022 | |||||||||||||
.Dt sizeof 7 | |||||||||||||
.Os | |||||||||||||
.Sh NAME | |||||||||||||
.Nm sizeof | |||||||||||||
operator | |||||||||||||
.Nd yield the storage size of the given operand | |||||||||||||
.Sh SYNTAX | |||||||||||||
.Nm Vt ( type ) | |||||||||||||
.br | |||||||||||||
.Nm Vt expression | |||||||||||||
pauamma_gundo.com: Not needed IIRC. | |||||||||||||
Done Inline ActionsWithout, I get both formatted on the same line: sizeof (type) sizeof expression But I want sizeof (type) jschauma_netmeister.org: Without, I get both formatted on the same line:
sizeof (type) sizeof expression
But I want… | |||||||||||||
Not Done Inline ActionsYeah, I was thinking of .Fn. pauamma_gundo.com: Yeah, I was thinking of .Fn. | |||||||||||||
.Sh DESCRIPTION | |||||||||||||
The unary | |||||||||||||
.Nm | |||||||||||||
operator yields the storage size of an expression or | |||||||||||||
data type in bytes. | |||||||||||||
.Sh DETAILS | |||||||||||||
Not Done Inline ActionsThis is misleading. sizeof() is never evaluated at runtime. brooks: This is misleading. sizeof() is never evaluated at runtime. | |||||||||||||
Not Done Inline ActionsAre you sure? For variable-length arrays, it is. kib: Are you sure? For variable-length arrays, it is. | |||||||||||||
Done Inline ActionsRemoved "at runtime". I think the rationale holds without anyway. jschauma_netmeister.org: Removed "at runtime". I think the rationale holds without anyway. | |||||||||||||
The size of data types in C (such as e.g., integers or | |||||||||||||
pointers) may differ across hardware platforms and | |||||||||||||
implementations. | |||||||||||||
For example, systems on which integers, longs, and | |||||||||||||
pointers are using 32 bits (e.g., i386) are referred | |||||||||||||
to as using the "ILP32" data model, systems using | |||||||||||||
64 bit longs and pointers (e.g., amd64 / x86_64) | |||||||||||||
as the "LP64" data model. | |||||||||||||
.Pp | |||||||||||||
As it may be necessary or useful for a program to be able | |||||||||||||
to determine the storage size of a data type or | |||||||||||||
object, | |||||||||||||
.Nm | |||||||||||||
yields that size in | |||||||||||||
.Em char sized units . | |||||||||||||
Not Done Inline ActionsBSD also historically provided NBBY symbol in sys/param.h, it is used quite often. kib: BSD also historically provided NBBY symbol in sys/param.h, it is used quite often. | |||||||||||||
Done Inline ActionsNoted! jschauma_netmeister.org: Noted! | |||||||||||||
As a result, | |||||||||||||
.Pf ' Vt sizeof(char) Ns ' | |||||||||||||
is always guaranteed to be | |||||||||||||
1. | |||||||||||||
(The number of bits per | |||||||||||||
.Vt char | |||||||||||||
is given by the | |||||||||||||
.Dv CHAR_BIT | |||||||||||||
definition in the | |||||||||||||
.In limits.h | |||||||||||||
header; many systems also provide the "number of bits | |||||||||||||
per byte" definition as | |||||||||||||
Not Done Inline ActionsIs LP64 here the same thing as LLP64 above? pauamma_gundo.com: Is LP64 here the same thing as LLP64 above? | |||||||||||||
Done Inline ActionsIt's not - good catch! "LLP64" is "long long integer", with a "long" being 32 bits. I'm updating the diff with the correction to use "LP64" consistently. jschauma_netmeister.org: It's not - good catch! "LLP64" is "long long integer", with a "long" being 32 bits.
I'm… | |||||||||||||
.Dv NBBY | |||||||||||||
in the | |||||||||||||
.In sys/param.h | |||||||||||||
header.) | |||||||||||||
.Sh EXAMPLES | |||||||||||||
The following examples illustrate the possible results | |||||||||||||
of calling | |||||||||||||
.Nm | |||||||||||||
on an ILP32 vs. an LP64 system: | |||||||||||||
.Pp | |||||||||||||
When applied to a simple variable or data type, | |||||||||||||
.Nm | |||||||||||||
returns the storage size of the data type of the | |||||||||||||
object: | |||||||||||||
.Bl -column -offset indent \ | |||||||||||||
".Li sizeof(struct flex)" ".Sy Result (ILP32)" ".Sy Result (LP64)" | |||||||||||||
.It Sy Object or type \ | |||||||||||||
Ta Sy Result (ILP32) \ | |||||||||||||
Ta Sy Result (LP64) | |||||||||||||
.It Li sizeof(char) \ | |||||||||||||
Ta 1 \ | |||||||||||||
Ta 1 | |||||||||||||
.It Li sizeof(int) \ | |||||||||||||
Ta 4 \ | |||||||||||||
Ta 4 | |||||||||||||
.It Li sizeof(long) \ | |||||||||||||
Ta 4 \ | |||||||||||||
Ta 8 | |||||||||||||
.It Li sizeof(float) \ | |||||||||||||
Ta 4 \ | |||||||||||||
Ta 4 | |||||||||||||
.It Li sizeof(double) \ | |||||||||||||
Ta 8 \ | |||||||||||||
Ta 8 | |||||||||||||
.It Li sizeof(char *) \ | |||||||||||||
Ta 4 \ | |||||||||||||
Ta 8 | |||||||||||||
.El | |||||||||||||
.Pp | |||||||||||||
For initialized data or uninitialized arrays of a | |||||||||||||
fixed size known at compile time, | |||||||||||||
.Nm | |||||||||||||
will return the correct storage size: | |||||||||||||
.Bd -literal -offset indent | |||||||||||||
#define DATA "1234567890" | |||||||||||||
char buf1[] = "abc"; | |||||||||||||
char buf2[1024]; | |||||||||||||
char buf3[1024] = { 'a', 'b', 'c' }; | |||||||||||||
.Ed | |||||||||||||
.Bl -column -offset indent \ | |||||||||||||
".Li sizeof(struct flex)" ".Sy Result" | |||||||||||||
Done Inline Actions
pauamma_gundo.com: | |||||||||||||
.It Sy Object or type \ | |||||||||||||
Ta Sy Result | |||||||||||||
.It Li sizeof(DATA) \ | |||||||||||||
Ta 11 | |||||||||||||
.It Li sizeof(buf1) \ | |||||||||||||
Ta 4 | |||||||||||||
.It Li sizeof(buf2) \ | |||||||||||||
Ta 1024 | |||||||||||||
.It Li sizeof(buf3) \ | |||||||||||||
Ta 1024 | |||||||||||||
.El | |||||||||||||
.Pp | |||||||||||||
The examples above are the same for ILP32 and LP64 | |||||||||||||
platforms, as they are based on character units. | |||||||||||||
.Pp | |||||||||||||
When applied to a struct or union, | |||||||||||||
Not Done Inline ActionsIt might be worth including an example that illustrates the difference in padding of 64-bit types between i386 and other architectures. Something like: struct s { int I; uint64_t i64; }; brooks: It might be worth including an example that illustrates the difference in padding of 64-bit… | |||||||||||||
Done Inline ActionsYeah, makes sense. Added that. jschauma_netmeister.org: Yeah, makes sense. Added that. | |||||||||||||
.Nm | |||||||||||||
returns the total number of bytes in the object, | |||||||||||||
including any internal or trailing padding used to | |||||||||||||
align the object in memory. | |||||||||||||
This result may thus be larger than if the storage | |||||||||||||
size of each individual member had been added: | |||||||||||||
.Bd -literal -offset indent | |||||||||||||
struct s1 { | |||||||||||||
char c; | |||||||||||||
} | |||||||||||||
struct s2 { | |||||||||||||
char *s; | |||||||||||||
int i; | |||||||||||||
} | |||||||||||||
struct s3 { | |||||||||||||
char *s; | |||||||||||||
int i; | |||||||||||||
int j; | |||||||||||||
} | |||||||||||||
struct s4 { | |||||||||||||
int i; | |||||||||||||
uint64_t i64; | |||||||||||||
}; | |||||||||||||
struct s5 { | |||||||||||||
struct s1 a; | |||||||||||||
struct s2 b; | |||||||||||||
struct s3 c; | |||||||||||||
struct s4 d; | |||||||||||||
} | |||||||||||||
.Ed | |||||||||||||
.Bl -column -offset indent \ | |||||||||||||
".Li sizeof(struct flex)" ".Sy Result (ILP32) " ".Sy Result (LP64)" | |||||||||||||
.It Sy Object or type \ | |||||||||||||
Ta Sy Result (ILP32) \ | |||||||||||||
Ta Sy Result (LP64) | |||||||||||||
.It Li sizeof(struct s1) \ | |||||||||||||
Ta 1 \ | |||||||||||||
Ta 1 | |||||||||||||
.It Li sizeof(struct s2) \ | |||||||||||||
Ta 8 \ | |||||||||||||
Ta 16 | |||||||||||||
.It Li sizeof(struct s3) \ | |||||||||||||
Ta 12 \ | |||||||||||||
Ta 16 | |||||||||||||
.It Li sizeof(struct s4) \ | |||||||||||||
Ta 12 \ | |||||||||||||
Ta 16 | |||||||||||||
.It Li sizeof(struct s5) \ | |||||||||||||
Ta 36 \ | |||||||||||||
Ta 56 | |||||||||||||
.El | |||||||||||||
.Pp | |||||||||||||
When applied to a struct containing a flexible array | |||||||||||||
member, | |||||||||||||
.Nm | |||||||||||||
returns the size of the struct | |||||||||||||
.Em without | |||||||||||||
the array, although again possibly including any | |||||||||||||
padding the compiler deemed appropriate: | |||||||||||||
.Bd -literal -offset indent | |||||||||||||
struct flex { | |||||||||||||
char c; | |||||||||||||
long b; | |||||||||||||
char array[]; | |||||||||||||
} | |||||||||||||
.Ed | |||||||||||||
.Bl -column -offset indent \ | |||||||||||||
".Li sizeof(struct flex)" ".Sy Result (ILP32) " ".Sy Result (LP64)" | |||||||||||||
.It Sy Object or type \ | |||||||||||||
Ta Sy Result (ILP32) \ | |||||||||||||
Ta Sy Result (LP64) | |||||||||||||
.It Li sizeof(struct flex) \ | |||||||||||||
Ta 8 \ | |||||||||||||
Ta 16 | |||||||||||||
Not Done Inline ActionsThen, mention the handy nitmes() macro from sys/param.h. kib: Then, mention the handy nitmes() macro from sys/param.h. | |||||||||||||
Done Inline ActionsAdded a note below. jschauma_netmeister.org: Added a note below. | |||||||||||||
.El | |||||||||||||
.Pp | |||||||||||||
One of the more common uses of the | |||||||||||||
.Nm | |||||||||||||
operator is to determine the correct amount of memory | |||||||||||||
to allocate: | |||||||||||||
.Bd -literal -offset indent | |||||||||||||
int *nums = calloc(512, sizeof(int)); | |||||||||||||
.Ed | |||||||||||||
.Pp | |||||||||||||
The | |||||||||||||
.Nm | |||||||||||||
operator can be used to calculate the number of | |||||||||||||
elements in an array by dividing the size of the array | |||||||||||||
by the size of one of its elements: | |||||||||||||
.Bd -literal -offset indent | |||||||||||||
int nums[] = { 1, 2, 3, 4, 5 }; | |||||||||||||
const int howmany = sizeof(nums) / sizeof(nums[0]); | |||||||||||||
.Ed | |||||||||||||
.Pp | |||||||||||||
Many systems provide this shortcut as the macro | |||||||||||||
.Dv ntimes() | |||||||||||||
via the | |||||||||||||
.Dv sys/param.h | |||||||||||||
header file. | |||||||||||||
.Sh RESULT | |||||||||||||
The result of the | |||||||||||||
.Nm | |||||||||||||
operator is an unsigned integer type, defined in the | |||||||||||||
.Dv stddef.h | |||||||||||||
header as a | |||||||||||||
Done Inline Actions
pauamma_gundo.com: | |||||||||||||
.Vt size_t . | |||||||||||||
.Sh NOTES | |||||||||||||
It is a common mistake to apply | |||||||||||||
.Nm | |||||||||||||
to a dynamically allocated array: | |||||||||||||
.Bd -literal -offset indent | |||||||||||||
char *buf; | |||||||||||||
if ((buf = malloc(BUFSIZ)) == NULL) { | |||||||||||||
perror("malloc"); | |||||||||||||
} | |||||||||||||
/* Warning: wrong! */ | |||||||||||||
(void)strncat(buf, input, sizeof(buf) - 1); | |||||||||||||
.Ed | |||||||||||||
.Pp | |||||||||||||
In that case, the operator will return the storage | |||||||||||||
size of the pointer | |||||||||||||
.Pf (' Vt sizeof(char *) Ns '), | |||||||||||||
not the | |||||||||||||
allocated memory. | |||||||||||||
.Pp | |||||||||||||
.Nm | |||||||||||||
determines the | |||||||||||||
.Ev size | |||||||||||||
of the result of the expression given, but | |||||||||||||
.Em does not | |||||||||||||
evaluate the expression: | |||||||||||||
.Bd -literal -offset indent | |||||||||||||
int a = 42; | |||||||||||||
printf("%ld - %d\\n", sizeof(a = 10), a); /* Result: "4 - 42" */ | |||||||||||||
.Ed | |||||||||||||
.Pp | |||||||||||||
Since it is evaluated by the compiler and not the | |||||||||||||
preprocessor, the | |||||||||||||
.Nm | |||||||||||||
operator cannot be used in a preprocessor expression. | |||||||||||||
.Pp | |||||||||||||
The | |||||||||||||
.Nm | |||||||||||||
operator cannot be used on a bit-field object, a | |||||||||||||
function type, or an incomplete type. | |||||||||||||
.Sh SEE ALSO | |||||||||||||
.Xr arch 7 , | |||||||||||||
.Xr operator 7 | |||||||||||||
.Sh STANDARDS | |||||||||||||
The | |||||||||||||
.Nm | |||||||||||||
operator conforms to | |||||||||||||
.St -ansiC . | |||||||||||||
.Pp | |||||||||||||
Handling of flexible array members in structures | |||||||||||||
conforms to | |||||||||||||
.St -isoC-99 . | |||||||||||||
.Sh AUTHORS | |||||||||||||
This manual page was written by | |||||||||||||
.An Jan Schaumann Aq Mt jschauma@netmeister.org . |
Not needed IIRC.