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_t
2, 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 typewchar_t
, that it also declares the typebyte
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
andstd::T
are reserved to the implementation[.]
3)[extern.types]/1
[...] when defined,
::T
shall be identical tostd::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
andstddef.h
header files define a datatype calledsize_t
1 which is used to represent the size of an object. Library functions that take sizes expect them to be of typesize_t
, and the sizeof operator evaluates tosize_t
.The actual type of
size_t
is platform-dependent; a common mistake is to assumesize_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
Does Scopeguard Use Really Lead to Better Code
How to Use Capturestackbacktrace to Capture the Exception Stack, Not the Calling Stack
Visual Studio Project Out of Date
Avoid Exponential Grow of Const References and Rvalue References in Constructor
Node Packages Not Building on Windows 8.1 - Missing Microsoft.Cpp.Default.Props
Google Protocol Buffers Compare
Meaningful Stack Traces for Address Sanitizer in Gcc
Are There Any Issues with Allocating Memory Within Constructor Initialization Lists
Getting a Buffer into a Stringstream in Hex Representation:
Where How to Use List Initialization
Should We Still Be Optimizing "In the Small"
Is Std::String Thead-Safe with Gcc 4.3
What Is the Use of Volatile Keyword
Error Lnk2005: New and Delete Already Defined in Libcmtd.Lib(New.Obj)
What Is Copy/Move Constructor Choosing Rule in C++? When Does Move-To-Copy Fallback Happen
Understanding the Different Clocks of Clock_Gettime()
Weird Undefined Symbols of Static Constants Inside a Struct/Class