sizeof
is a C keyword. It returns the size in a type named size_t
. However, size_t
is not a keyword, but is defined primarily in stddef.h
and probably other C standard header files too.
Consider a scenario where you want to create a C program which does not include any C standard headers or libraries. (Like for example, if you are creating an OS kernel.) Now, in such code, sizeof
can be used (it is a C keyword, so it is a part of the language), but the type that it returns (size_t
) is not available!
Does not this signify some kind of a problem in the C standard specification? Can you clarify this?
I think that the main reasons that
size_t
is not a keyword are:For example, in discussing the next major revision of the C++ standard, Stroustrup had this to say:
There is no reason not to include stddef.h, even if you are working on a kernel - it defines type sizes for your specific compiler that any code will need.
Note also that almost all C compilers are self-compiled. The actual compiler code for the sizeof operator will therefore use size_t and reference the same stddef.h file as does user code.
sizeof
is a keyword because, despite it's name and usage, it is an operator like+
or=
or<
rather than a function likeprintf()
oratoi()
orfgets()
. A lot of people forget (or just don't know) thatsizeof
is actually an operator, and is always resolved at compile-time rather than at runtime.The C language doesn't need
size_t
to be a usable, consistent language. That's just part of the standard library. The C language needs all operators. If, instead of+
, C used the keywordplus
to add numbers, you would make it an operator.Besides, I do semi-implicit recasting of
size_t
s tounsigned int
s (and regularint
s, but Kernighan and Ritchie will someday smite me for this) all the time. You can assign the return type of asizeof
to an int if you like, but in my work I'm usually just passing it straight on to amalloc()
or something.Some headers from the C standard are defined for a freestanding environment, i.e. fit for use e.g. in an operating system kernel. They do not define any functions, merely defines and typedefs.
They are float.h, iso646.h, limits.h, stdarg.h, stdbool.h, stddef.h and stdint.h.
When working on an operating system, it isn't a bad idea to start with these headers. Having them available makes many things easier in your kernel. Especially stdint.h will become handy (uint32_t et al.).
The simple reason is because it is not a fundamental type. If you look up the C standard you will find that fundamental types include
int
,char
etc but notsize_t
. Why so? As others have already pointed out,size_t
is an implementation specific type (i.e. a type capable of holding the size in number of "C bytes" of any object).On the other hand,
sizeof
is an (unary) operator. All operators are keywords.Look up the difference between a hosted implementation of C and a freestanding C implementation. The freestanding (C99) implementation is required to provide headers:
<float.h>
<iso646.h>
<limits.h>
<stdarg.h>
<stdbool.h>
<stddef.h>
<stdint.h>
These headers do not define any functions at all. They define parts of the language that are somewhat compiler specific (for example, the
offsetof
macro in<stddef.h>
, and the variable argument list macros and types in<stdarg.h>
), but they can be handled without actually being built into the language as full keywords.This means that even in your hypothetical kernel, you should expect the C compiler to provide these headers and any underlying support functions - even though you provide everything else.