I have such expressions in my code:
QByteArray idx0 = ...
unsigned short ushortIdx0;
if ( idx0.size() >= sizeof(ushortIdx0) ) {
// Do something
}
But I'm getting the warning:
warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if ( idx0.size() >= sizeof(ushortIdx0) ) { ~~~~~~~~~~~~^~~~~~~~~~
Why size()
of QByteArray
is returned as int
rather than unsigned int
? How can I get rid of this warning safely?
The reason why is a duplicate part of the question, but the solution to the type mismatch is a valid problem to solve. For the comparisons of the kind you're doing, it'd probably be useful to factor them out, as they have a certain reusable meaning:
Hopefully you'll have just a few kinds of such comparisons, and it'd make most sense to DRY (do not repeat yourself) and instead of a copypasta of casts, use functions dedicated to the task - functions that also express the intent of the original comparison. It then becomes easy to centralize handling of any corner cases you might wish to handle, i.e. when
sizeof(T) > INT_MAX
.Another approach would be to define a new type to wrap
size_t
and adapt it to the types you need to use it with:This would conceptually extend
sizeof
and specialize it for comparison(s) and nothing else.Some folk feel that the introduction of
unsigned
types into C all those years ago was a bad idea. Such types found themselves introduced into C++, where they are deeply embedded in the C++ Standard Library and operator return types.Yes,
sizeof
must, by the standard, return anunsigned
type.The Qt developers adopt the modern thinking that the
unsigned
types were a bad idea, and favour instead making the return type ofsize
asigned
type. Personally I find it idiosyncratic.To solve, you could (i) live with the warning, (ii) switch it off for the duration of the function, or (iii) write something like
at the expense of clarity.
Because in Qt containers (like: QByteArray, QVector, ...) there are functions which can return a negative number, like: indexOf, lastIndexOf, contains, ... and some can accept negative numbers, like: mid, ...; So to be class-compatible or even framework-compatibe, developers use a signed type (int).
You can use standard c++ casting:
I literally have no idea why Qt chose a signed return for
size()
. However, there are good reasons to use a signed instead of an unsigned.One infamous example where a
unsigned size()
fails miserably is this quite innocent looking loop:Its not too uncommon to make the loop body operate on two elements and in that case its seems to be a valid choice to iterate only till
some_container.size() - 1
.However, if the container is empty
some_container.size() - 1
will silently (unsigned overflow is well defined) turn into the biggest value for the unsigned type. Hence, instead of avoiding the out-of-bounds access it leads to the maximum out of bounds you can get.Note that there are easy fixes for this problem, but if
size()
does return a signed value, then there is no issue that needs to be fixed in the first place.