Difference between size_t and std::size_t

should i use size_t or std size_t
std c size_t
size_t header
c++ cout size_t
signed size_t
initialize size_t c
size_type
c ssize_t

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?

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.

Is it poor form to use C features such as the size_t type instead of their, typedef /*implementation-defined*/ size_t;. std::size_t is the unsigned integer type of the result of the sizeof operator� std::size_t size_type_abs(std::size_t a, std::size_t b) { return a < b ? b - a : a - b; } This might be about the same efficiency as your version, or it might be marginally better. I'd be rather surprised to see it any less efficient though. I see little difference in readability between the two, so no real preference on that account.

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.

std::size_t, I've observed: No guideline in the CppCoreGuidelines yet use int over size_t and std::size_t as it looks simpler, avoid arithmetic Units has a nice trick to allow to distinguish dimensionless units that I would prefer myself. C++11 and later implements template std::make_signed, but it's somewhat grey area if using size_t as its parameter is well-defined. In c++20 use of this template with types not allowed by standard results in ill-formed code, but existing implementations allow use of size_t – Swift - Friday Pie Jul 1 at 15:34

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.

Use of int, size_t, std::size_t or a custom class? � Issue #848 � isocpp , Examples � std::string::crbegin() and std::string::crend() in C++ with Examples size_t is an unsigned integral data type which is defined in various strlen() uses size_t because the length of any string carefully when used in a loop. Array Type Manipulation in C++ � Difference between fundamental� It often happens to be std::size_t, but: (a) Maybe not, I'm not even sure (thanks @Ayxan); (b) you shouldn't care about whether it's std::size_t or not, usually. But even the above options are not right. There's a deeper problem here - and the problem is that find() should really return an [std::optional][2]<std::string::size_type>. Except that

What is the size_t data type in C?, In C++ a std::string could, in theory, be up to the limit of the std::size_t type. This is an unsigned integer type. Different compilers will map this to different unsigned� for (std::size_t i = 99; i >= 0; i--) { // This is an infinite loop } If you are just doing a loop, you might want to use just a plain int because of the situation above. There should be no performance difference between using int and std::size_t. If you need an exact size, then you should use neither int nor size_t, but rather the types

What is the difference between size_t and auto in C++?, The fast type (std::int_fast#_t) provides the fastest signed integer type with a width of at least value) return a value of type std::size_t. std::size_t is defined as an unsigned integral type, What's the difference between int#_t and int_least#_t ? According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3). The standard also recommends that size_t shouldn't have an integer conversion rank greater than long if possible, ie casting size_t to unsigned long is unproblematic if the recommendation is followed.

4.6 — Fixed-width integers and size_t, std::size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit� size_t is defined by the C standard to be the unsigned integer return type of the sizeof operator (C99 6.3.5.4.4), and the argument of malloc and friends (C99 7.20.3.3 etc). The actual range is set such that the maximum (SIZE_MAX) is at least 65535 (C99 7.18.3.2).

Comments
  • I'd be interested to know if the C++ spec links std::size_t to the C size_t type.
  • See similar question: link
  • Thats brings to another Q, If STL already imports size_t through C (cstddef) the why it has its own another version again?
  • @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: 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!
  • @BenHymers The standard specifies what the standard headers declare, and they are not allowed to declare any other non-reserved names. The header <cstddef> may or may not declare ::size_t, so you cannot rely on it being there or being absent, unless specifically including <stddef.h> or another header from the C library which is guaranteed to declare it.
  • @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 <stddef.h>, so you don't always need to qualify it with std::.
  • So portable code shouldn't rely on the std::T variants being defined?
  • @Mankarse: You shouldn't rely on them being defined if you only include the C version of the corresponding header. If you #include <stddef.h> then std::size_t might or might not be available. If you #include <cstddef> then std::size_t is available, but size_t might not be.
  • @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.
  • Personally, I never bother with the <cxxxxx> headers or the std:: variants of identifiers that come from the C shore. I stick with <xxxxx.h> for the standard C headers - it's never been a problem. So, I'd use <stddef.h> 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.
  • As Nawaz points out, it's actually the other way around. You can't include <cstddef> and expect to get ::size_t, but if you include <stddef.h> you will get std::size_t.
  • @MSalters, I don't follow. Including <stddef.h> will only get you ::size_t.