Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a signed `sizeof` alternative in Qt

Tags:

c++

qt

Sizes of Qt containers return (signed) int. And we know in Qt, a lot more is using int instead of the unsigned type size_t in order to do arithmetic operations without the need for casting. See Why does Qt use a signed int type for its container classes & Why QVector.size() returns int

As the language keyword sizeof returns the size_t type, is there a Qt alternative for this?

like image 845
DrumM Avatar asked Dec 13 '18 08:12

DrumM


2 Answers

You can make your own, safe version:

template<std::size_t s>
constexpr int safeIntCast()
{
    static_assert(s <= std::numeric_limits<int>::max(), "Type too large for ssizeof()!");
    return static_cast<int>(s);
}

#define ssizeof(x) safeIntCast<sizeof(x)>()

/// Usage

static_assert(ssizeof(int) == 4);
static_assert(ssizeof(1.0) == 8);

static_assert(ssizeof(std::declval<int>()) == 4);
static_assert(ssizeof(int[1000000000000]) > 4); // Conversion problem is caught!

Demo

It has the same semantics as sizeof but yields an int while ensuring that the conversion does not overflow.

like image 110
Max Langhof Avatar answered Sep 28 '22 15:09

Max Langhof


The correct answer is that this is impossible. std::size_t can be std::uintmax_t, meaning that even std::intmax_t, the largest standards compliant type, cannot hold all values of std::size_t.

In most cases, you won't have to worry about it. An int (or a long long) will hold the size of your objects in most cases, so you can just cast to it: static_cast<long long>(sizeof(T)). If you are doing pointer arithmetic, consider using std::ptrdiff_t, or not using sizeof and doing end() - begin().

like image 39
Artyer Avatar answered Sep 28 '22 15:09

Artyer