Reputation: 78498
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?
Upvotes: 27
Views: 10778
Reputation: 70293
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.).
Upvotes: 9
Reputation: 340218
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:
The C++0x improvements should be done in such a way that the resulting language is easier to learn and use. Among the rules of thumb for the committee are:
...
- Prefer standard library facilities to language extensions
...
Upvotes: 4
Reputation: 754090
Does not this signify some kind of a problem in the C standard specification?
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.
Upvotes: 8
Reputation: 111150
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 not size_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.
Upvotes: 1
Reputation: 3483
It does not literally return a value of type size_t since size_t is not a concrete type in itself, but rather a typedef to an unspecified built-in type. Typedef identifiers (such as size_t) are completely equivalent to their respective underlying types (and are converted thereto at compile time). If size_t is defined as an unsigned int on your platform, then sizeof returns an unsigned int when it is compiled on your system. size_t is just a handy way of maintaining portability and only needs to be included in stddef.h if you are using it explicitly by name.
Upvotes: 47
Reputation:
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.
Upvotes: 3
Reputation: 46781
size_t is not a keyword by necessity. Different architectures often have different sizes for integral types. For example a 64 bit machine is likely to have an unsigned long long as size_t if they didn't decide to make int a 64 bit datatype.
If you make sizeof a builtin type to the compiler, then it will take away the power to do cross compilation.
Also, sizeof is more like a magic compile time macro (think c++ template) which explains why it is a keyword instead of defined type.
Upvotes: 1
Reputation: 7146
size_t is actually a type - often an unsigned int. Sizeof is an operator that gives the size of a type. The type returned by sizeof is actually implementation-specific, not a C standard. It's just an integer.
Edit: To be very clear, you do not need the size_t type in order to use sizeof. I think the answer you're looking for is - Yes, it is inconsistent. However, it doesn't matter. You can still practically use sizeof correctly without having a size_t definition from a header file.
Upvotes: 2
Reputation: 75419
sizeof
is a keyword because, despite it's name and usage, it is an operator like +
or =
or <
rather than a function like printf()
or atoi()
or fgets()
. A lot of people forget (or just don't know) that sizeof
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 keyword plus
to add numbers, you would make it an operator.
Besides, I do semi-implicit recasting of size_t
s to unsigned int
s (and regular int
s, but Kernighan and Ritchie will someday smite me for this) all the time. You can assign the return type of a sizeof
to an int if you like, but in my work I'm usually just passing it straight on to a malloc()
or something.
Upvotes: 14