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
.
In fact the synopsis (included in the C++ standard) of several headers specifially include size_t
as well as further headers define the type size_t
(based on the C standard as the <cX>
headers are just ISO C <X.h>
headers with noted changes where removal of size_t
is not indicated).
The C++ standard however, refers to <cstddef>
for the definition of std::size_t
- in 18.2 Types,
- in 5.3.3 Sizeof,
- in 3.7.4.2 Deallocation functions (which refers to 18.2) and
- in 3.7.4.1 Allocation functions (also refers to 18.2).
Therefore and because of the fact that <cstddef>
only introduces types and no functions, I'd stick to this header to make std::size_t
available.
Note a few things :
-
The type of
std::size_t
is obtainable usingdecltype
without including a headerIf you're planning to introduce a typedef in your code anyway (i.e. because you write a container and want to provide a
size_type
typedef) you can use the globalsizeof
,sizeof...
oralignof
operators to define your type without including any headers at all since theose operators returnstd::size_t
per standard definition and you can usedecltype
on them:using size_type = decltype(alignof(char));
-
std::size_t
is not per se globally visible although functions withstd::size_t
arguments are.The implicitly declared global allocation and deallocation functions
void* operator new(std::size_t); void* operator new[](std::size_t); void operator delete(void*); void operator delete[](void*);
do NOT introduce
size_t
,std
orstd::size_t
andreferring to
std
orstd::size_t
is ill-formed unless the name has been declared by including the appropriate header. -
The user may not redefine
std::size_t
although it is possible to have multiple typedefs referring to the same type in the same namespace.Although, the occurrence of multiple definitions of
size_t
withinstd
is perfectly valid as per 7.1.3 / 3, it is not allowed to add any declarations tonamespace std
as per 17.6.4.2.1 / 1:The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified.
Adding a proper typedef for
size_t
to the namespace does not violate 7.1.3 but it does violate 17.6.4.2.1 and leads to undefined behaviour.Clarification: Try not to misinterpret 7.1.3 and do not add declarations or definitions to
std
(except a few template specialization cases where a typedef is not a template specialization). Extending thenamespace std