std::size_t
is commonly used for array indexing and loop counting. By definition, std::size_t
is the unsigned integer type of the result of the sizeof
operator as well as the sizeof...
operator and the alignof
operator (since C++11). It's defined in the following headers:
<cstddef>
<cstdio>
<cstdlib>
<cstring>
<ctime>
<cwchar>
To my understanding, the type returned by these operators is implementation-defined.
What I want is to define a custom size_t
in order to avoid pulling unnecessary stuff from any of the headers mentioned above in a .cpp
file of mine, since in my file I only need std::size_t
.
In C++11 and above, I thought I could use the following alias:
using size_t = decltype(sizeof(1));
However, I'd like to define a size_t
type for pre-C++11 compilers in a portable/cross-platform way.
So is there a portable way to define size_t
for pre-C++11?
size_t is a base unsigned integer memsize-type defined in the standard library of C/C++ languages. This type is described in the header file stddef. h for C and in the file cstddef for C++. Types defined by the header file stddef.
According to the 1999 C Standard, size_t is clearly supposed to be unsigned. In clause 7.17, Common definitions , it says: The following types and macros are defined in the standard header .
The name size_t essentially means "size type", and you will typically see this data type used to specify the size or length of things - like the length of a C string returned by the strlen() function, for example. This is not one of the "built-in" data types of C/C++.
However, size_t is not a keyword, but is defined primarily in stddef. h and probably other C standard header files too. Consider a scenario where you want to create a C program which does not include any C standard headers or libraries. (Like for example, if you are creating an OS kernel.)
Well theoretically, if listing of all possible (unsigned) candidates for size_t
doesn't bother you, you could make use of SFINAE:
template <class T, class N = void, bool = sizeof(T) == sizeof(sizeof(T))>
struct TL {
typedef typename N::type type;
};
template <class T, class N>
struct TL<T, N, true> {
typedef T type;
};
typedef TL<unsigned short,TL<unsigned int, TL<unsigned long, TL<unsigned long long> > > >::type SizeT;
[live demo]
Edit:
Workaround for compilers which differentiate unsigned long
from unsigned long long
despite the fact that they're assuming sizeof(unsigned long) == sizeof(unsigned long long)
:
template <class U>
U *declptrval(U);
template <class U>
char is_exact(U *);
template <class U>
short is_exact(...);
template <class T, class N = void, bool = sizeof(is_exact<T>(declptrval(sizeof(T))))==sizeof(char)>
struct TL {
typedef typename N::type type;
};
template <class T, class N>
struct TL<T, N, true> {
typedef T type;
};
typedef TL<unsigned short,TL<unsigned int, TL<unsigned long, TL<unsigned long long> > > >::type SizeT;
[live demo]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With