Which Header Should I Include for 'Size_T'

Which header should I include for `size_t`?

Assuming I wanted to minimize the functions and types I was importing I'd go with cstddef as it doesn't declare any functions and only declares 6 types. The others focus on particular domains (strings, time, IO) that may not matter to you.

Note that cstddef only guarantees to define std::size_t, that is, defining size_t in namespace std, although it may provide this name also in the global namespace (effectively, plain size_t).

In contrast, stddef.h (which is also a header available in C) guarantees to define size_t in the global namespace, and may also provide std::size_t.

Where is size_t Defined?

I presume this technically means that the definition of size_t in the global namespace has been deprecated?

Yes... but.

The Standard only mandates that std::size_t must be defined1 by <cstddef>, it does not disallow an implementation to define ::size_t2, but if the implementation does, the two definitions must match3.

As a conclusion, you should use std::size_t and should neither rely on ::size_t to be defined nor define it.

The following are UB:

// DON'T
using size_t = std::size_t; // UB
using size_t = decltype(sizeof 1); // UB

1) [cstddef.syn]

namespace std {
using ptrdiff_­t = see below;
using size_­t = see below;
using max_­align_­t = see below;
using nullptr_­t = decltype(nullptr);

[...]

The contents and meaning of the header <cstddef> are the same as the C standard library header <stddef.h>, except that it does not declare the type wchar_­t, that it also declares the type byte and its associated operations ([support.types.byteops]), and as noted in [support.types.nullptr] and [support.types.layout].

2)[extern.types]/1

For each type T from the C standard library (These types are [...] size_­t,[...].), the types ​::​T and std​::​T are reserved to the implementation[.]

3)[extern.types]/1

[...] when defined, ​::​T shall be identical to std​::​T.

Which header to include for size_t

My question is why is there not a single definition of size_t?

There is a single definition for std::size_t. It's just defined in multiple headers since those headers themselves use that definition.

Which header do I include, if I just want size_t?

Any of the ones that are specified to define it.

My choice is typically, <cstddef> because it is very small and has other definitions that I'm likely to need such as std::byte.

Why can I use size_t and std::size_t in MSVS without the traditional headers?

Strictly speaking your code is illegal. The size_t type is required to be declared in the following headers:

<cstddef>
<cstdio>
<cstdlib>
<cstring>
<ctime>
<cwchar>

But also the standard allows standard headers to include other standard headers. So most likely the header <vector> in the standard library used by MSVC includes one of the headers above. This is allowed, but not mandated by the standard so this will work on your setup, but can fail to work on other standard library implementations, even on a future version of the same one you are using.

So in conclusion try to include all the headers required by the standard for all the definitions you are using.

IMHO this is a faulty behavior, but is the required price C++ pays for backward compatibility to the inclusion system that seemed a reasonable design many years ago. The limitations and drawbacks of this are well known today and so the committee is working on modules, which is a modern alternative to the current inclusion mechanism.


As to why you can use size_t without std:::

<cstddef> is required to declare std::size_t and may also optionally declare (or bring in the declaration of) size_t in the global scope.

<stddef.h> is a C backward compatible header and it declares size_t at the global scope.

So either <cstddef> declares size_t at a global level and is included by <vector> or <stddef.h> is included by <vector> - most likely indirectly via <cstddef>.

https://stackoverflow.com/a/283023/2805305

C++ size_t doesn't need cstddef header?

size_t is really a grey area. std::size_t is the result type of sizeof, but sizeof is a built-in operator you can use without any #include at all. Consider this complete little program:

// no includes, no using namespace std

int main()
{
auto x = sizeof(int); // x is std::size_t
}

On top of that, Visual C++ has always behaved a bit strangely here. Even with settings like /permissive- /std:c++latest in the newest version of the compiler, it still allows the following illegal code:

// no includes, no using namespace std

int main()
{
size_t i = 0;
}

In fact, it would even allow this:

// no includes, no using namespace std

int main()
{
int ar[10];

for (size_t x = 0; x < 10; ++x)
ar[x] = x;

for (auto a : ar)
;

return 0;
}

Nevertheless, what others said about the indirect inclusion of headers is correct. To be precise, the C++ standard says the following about standard-library headers at §20.5.5.2:

A C++ header may include other C++ headers.

Which means that Visual C++ behaves correctly in your case anyway. Once you include <iostream>, the implementation is free to indirectly include one of the six standard C++ headers that define std::size_t, and your using namespace std; (which is evil) does the rest.

The C++ standard even guarantees some of such indirect inclusions, but this isn't one of them, so in order to make your code compatible with other compilers, you are strongly encouraged to include <cstddef> or one of the others that guarantee std::size_t.

Does std::size_t make sense in C++?

There seems to be confusion among the stackoverflow crowd concerning this

::size_t is defined in the backward compatibility header stddef.h . It's been part of ANSI/ISO C and ISO C++ since their very beginning. Every C++ implementation has to ship with stddef.h (compatibility) and cstddef where only the latter defines std::size_t and not necessarily ::size_t. See Annex D of the C++ Standard.

Where do I find the definition of size_t?

From Wikipedia

The stdlib.h and stddef.h header files define a datatype called size_t1 which is used to represent the size of an object. Library functions that take sizes expect them to be of type size_t, and the sizeof operator evaluates to size_t.

The actual type of size_t is platform-dependent; a common mistake is to assume size_t is the same as unsigned int, which can lead to programming errors,2 particularly as 64-bit architectures become more prevalent.

From C99 7.17.1/2

The following types and macros are defined in the standard header stddef.h

<snip>

size_t

which is the unsigned integer type of the result of the sizeof operator

Does it matter which header (cstddef, cstdio, cstdlib, etc.) I include to get the definition of size_t?

Can I include any header file and be sure that size_t would behave in the same way regardless of which header file I included?

Yes.

Are there any surprises I need to be aware of like including one header file would have surprising side-effects that including another header file would not have?

No.

Is there a coding convention or popular convention or practice regarding this that leads to most people including a specific header file to get the definition of size_t?

I personally prefer <cstddef> but I am not aware of any conventions.

preferred include header for std::size_t

Since this is part of the C library I think the C standard specified header is the right one: stddef.h, i.e. cstddef.

From C11:

7.19 Common definitions

The header defines the following macros and declares the following types. Some are also defined in other headers, as noted in their respective subclauses.

[...]
size_t which is the unsigned integer type of the result of the
sizeof operator;

This is after all a C++ question so I think a quote from the C++ standard is more appropriate:

18.2 Types

Table 30 describes the header <cstddef>.

Types: ptrdiff_t size_t max_align_t nullptr_t



Related Topics



Leave a reply



Submit