Ashwin Nanjappa
Ashwin Nanjappa

Reputation: 78498

C: Why isn't size_t a C keyword?

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

Answers (10)

DevSolar
DevSolar

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

Michael Burr
Michael Burr

Reputation: 340218

I think that the main reasons that size_t is not a keyword are:

  • there's no compelling reason for it to be. The designers of the C and C++ languages have always preferred to have language features be implemented in the library if possible and reasonable
  • adding keywords to a language can create problems for an existing body of legacy code. This is another reason they are generally resistant to adding new keywords.

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

Jonathan Leffler
Jonathan Leffler

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

dirkgently
dirkgently

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

Simon Broadhead
Simon Broadhead

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

anon
anon

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

Unknown
Unknown

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

Anthony
Anthony

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

Chris Lutz
Chris Lutz

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_ts to unsigned ints (and regular ints, 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

schnaader
schnaader

Reputation: 49719

From MSDN:

When the sizeof operator is applied to an object of type char, it yields 1

Even if you don't have stddef.h available/included and don't know about size_t, using sizeof you can get the size of objects relative to char.

Upvotes: 2

Related Questions