Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a custom cross-platform size_t type?

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?

like image 392
101010 Avatar asked Jun 13 '17 11:06

101010


People also ask

How is Size_t defined?

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.

Can Size_t be signed?

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 .

Is Size_t built in?

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++.

Is Size_t a keyword?

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.)


1 Answers

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]

like image 187
W.F. Avatar answered Sep 24 '22 00:09

W.F.