Search code examples
c++c++11typestype-conversioninteger-promotion

Why is unsigned short (multiply) unsigned short converted to signed int?


Why is unsigned short * unsigned short converted to int in C++11?

The int is too small to handle max values as demonstrated by this line of code.

cout << USHRT_MAX * USHRT_MAX << endl;

overflows on MinGW 4.9.2

-131071

because (source)

USHRT_MAX = 65535 (2^16-1) or greater*

INT_MAX = 32767 (2^15-1) or greater*

and (2^16-1)*(2^16-1) = ~2^32.


Should I expect any problems with this solution?

unsigned u = static_cast<unsigned>(t*t);

This program

unsigned short t;
cout<<typeid(t).name()<<endl;
cout<<typeid(t*t).name()<<endl;

gives output

t
i

on

gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)
gcc version 4.8.2 (GCC)
MinGW 4.9.2

with both

g++ p.cpp
g++ -std=c++11 p.cpp

which proves that t*t is converted to int on these compilers.


Usefull resources:

Signed to unsigned conversion in C - is it always safe?

Signed & unsigned integer multiplication

https://bytes.com/topic/c-sharp/answers/223883-multiplication-types-smaller-than-int-yields-int

http://www.cplusplus.com/reference/climits

http://en.cppreference.com/w/cpp/language/types


Edit: I have demonstrated the problem on the following image.

enter image description here


Solution

  • You may want to read about implicit conversions, especially the section about numeric promotions where it says

    Prvalues of small integral types (such as char) may be converted to prvalues of larger integral types (such as int). In particular, arithmetic operators do not accept types smaller than int as arguments

    What the above says is that if you use something smaller than int (like unsigned short) in an expression that involves arithmetic operators (which of course includes multiplication) then the values will be promoted to int.