What are the differences between size_t
and std::size_t
in terms of where they are declared, when they should be used and any other differentiating features?

- 9,193
- 6
- 52
- 57

- 39,818
- 11
- 97
- 141
-
I'd be interested to know if the C++ spec links std::size_t to the C size_t type. – Doug T. Apr 28 '11 at 04:43
-
See similar question: [link](http://stackoverflow.com/questions/237370/does-stdsize-t-make-sense-in-c) – Mankarse Apr 28 '11 at 05:35
3 Answers
C's size_t
and C++'s std::size_t
are both same.
In C, it's defined in <stddef.h>
and in C++, its defined in <cstddef>
whose contents are the same as C header (see the quotation below). Its defined as unsigned integer type of the result of the sizeof operator.
C Standard says in §17.7/2,
size_t which is the unsigned integer type of the result of the sizeof operator
And C++ Standard says (about cstddef
header) in §18.1/3,
The contents are the same as the Standard C library header , with the following changes.
So yeah, both are same; the only difference is that C++ defines size_t
in std
namespace.
Please also notice that the above line also says "with the following changes" which isn't referring to size_t
. Its rather referring to the new additions (mostly) made by C++ into the language (not present in C) which are also defined in the same header.
Wikipedia has very good info about range and storage size of size_t:
Range and storage size of 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,[3][4] when moving from 32 to 64-bit architecture, for example.
According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of at least 16 bits.
And the rest you can read from this page at wikipedia.

- 8,648
- 5
- 39
- 58

- 353,942
- 115
- 666
- 851
-
2Thats brings to another Q, If STL already imports size_t through C (cstddef) the why it has its own another version again? – Alok Save Apr 28 '11 at 04:51
-
49@Als: Strictly speaking, it is an error to say `size_t` without `using namespace std;` or `using std::size_t;`. However, most compilers allow it, and the Standard specifically allows them to allow it (§D.5/3). – Potatoswatter Apr 28 '11 at 05:03
-
10@Potatoswatter: Surely it can't be both an error and specifically allowed in the standard? If it's in the standard, it's not an error! – Ben Hymers Jul 30 '13 at 13:20
-
11@BenHymers The standard specifies what the standard headers declare, and they are not allowed to declare any other non-reserved names. The header `
` may or may not declare `::size_t`, so you cannot rely on it being there or being absent, unless specifically including ` – Potatoswatter Jul 30 '13 at 23:48` or another header from the C library which is guaranteed to declare it. -
5@Potatoswatter: Ah, I see what you mean now! I must have gotten confused by too many "allow"s in one sentence. I still think your first comment is too strong though; as you just said, `::size_t` is present e.g in `
`, so you don't always need to qualify it with `std::`. – Ben Hymers Jul 31 '13 at 08:28
From C++03 "17.4.3.1.4 Types":
For each type T from the Standard C library (footnote 169), the types ::T and std::T are reserved to the implementation and, when defined, ::T shall be identical to std::T.
And footnote 169:
These types are clock_t, div_t, FILE, fpos_t, lconv, ldiv_t, mbstate_t, ptrdiff_t, sig_atomic_t, size_t, time_t, tm, va_list, wctrans_t, wctype_t, and wint_t.

- 333,147
- 50
- 533
- 760
-
So portable code shouldn't rely on the `std::T` variants being defined? – Mankarse Apr 28 '11 at 05:24
-
6@Mankarse: You shouldn't rely on them being defined *if* you only include the C version of the corresponding header. If you `#include
` then `std::size_t` might or might not be available. If you `#include – Dennis Zickefoose Apr 28 '11 at 05:46` then `std::size_t` is available, but `size_t` might not be. -
5@Mankarse: The oposite. The C++ versions of the headers must define them in `std::` and the paragraph says that it may also define them in top-level namespace and if it does, it must define them identically in `std::` and top-level. Most compilers just include the C header and import the names to `std::`, so the symbols do end up defined in both. – Jan Hudec Apr 28 '11 at 06:32
-
4Personally, I never bother with the
headers or the `std::` variants of identifiers that come from the C shore. I stick with ` – Michael Burr Apr 28 '11 at 06:32` for the standard C headers - it's never been a problem. So, I'd use ` ` and `size_t` and never give a second thought to `std::size_t`; in fact, it never crosses my mind that there is (or might be) a `std::size_t`.
std::size_t is in fact stddef.h's size_t.
cstddef gives the following:
#include <stddef.h>
namespace std
{
using ::ptrdiff_t;
using ::size_t;
}
...effectively bringing the previous definition into the std namespace.

- 17,245
- 4
- 40
- 67

- 457
- 3
- 9
-
As Nawaz points out, it's actually the other way around. You can't include `
` and expect to get `::size_t`, but if you include ` – MSalters Apr 28 '11 at 08:40` you will get `std::size_t`. -
4
-
2
-
4@MSalters, I don't quite follow. Shouldn't it be the other way round?
comes from C++, thus should define the stuff in std::*? On the other hand, in a C header, like stddef.h, I would only expect the C type, i.e. ::size_t. – Ela782 Nov 18 '14 at 00:58 -
14@MSalters, since C++11 that's not accurate. If you include `
` you are guaranteed to get `std::size_t` and you might also get `::size_t` (but it's not guaranteed). If you include ` – Jonathan Wakely Nov 12 '16 at 23:22` you're guaranteed to get `::size_t` and you might also get `std::size_t` (but it's not guaranteed). It was different in C++03 but that was effectively unimplementable and fixed as a defect. -
This answer is outright incorrect. This is an assumption about the implementation that other implementations may not adhere too. The standard specifically states that `cstddef` will define `std::size_t`, but it may or may not introduce `::size_t` (it neither requires nor prohibits it0. Even if the implementation does introduce `::size_t`, that could be done either through placing a `using ::size_t;` into `namespace std` or placing a `using std::size_t;` into the global namespace, there's no way of guaranteeing which method an implementation will do it. – Pharap Dec 04 '19 at 23:15