is the standard explicitly demanding short to be implicitly cast to int?

why do I get a warning in the code below, both gcc and clang?!?!
is there a way to overload operator+(short,short)?
same problem with char instead of short!
why does the compliler implicitly cast start to int?
is it still type-safety when types just get cast behind my back?

#include <vector>
int main(){
short start=0;
std::vector<short> t{start+start};
}

gcc-7.3.0 gives
warning: narrowing conversion of '(((int)start) + ((int)start))' from 'int' to 'short int' inside { } [-Wnarrowing]
clang++ -std=c++17 in version 5.0.1 gives
error: non-constant-expression cannot be narrowed from type 'int' to 'short' in
initializer list [-Wc++11-narrowing]
which is even more cryptic considering I just add up two *short* integers...
Yes. It's called integral promotion. Whenever you do an arithmetic operation on types that are smaller than int the operands will be converted to int before the operation is carried out and the result will be an int.
Last edited on
closed account (E0p9LyTq)
You could try:

1
2
3
4
5
6
7
#include <vector>

int main()
{
   short start = 0;
   std::vector<short> t { static_cast<short>(start + start) };
}
Can someone please tell me the rationale behind this?

Wanna add two doubles together to put in a double array? Sure.
Wanna add two ints together to put int an int array? Go for it.
Wanna add two shorts together to put in a short array? Nope!

(Wanna use a template <typename T>?... well you'll get a compile error for short, but not int.)

If the only reason is "because it's easier for the CPU to work with full words instead of half words", I feel like that's just a cop-out implementation detail that shouldn't affect the pattern described above. As such, why isn't it just the same end-result behavior as integer overflow? If you add two ints together, you'd have to worry about them overflowing, just as you'd have to worry about two shorts overflowing (or wrapping around in the case of unsigned numbers).

Also, is the best solution for the OP really to just use bizarre casts to mask the fact that the the shorts are getting promoted into ints?
Last edited on
I wonder if the alignas specifier would work? Edit: Maybe in conjunction with an unscoped enum, with the type specified? Could it force the packing of 4 shorts into 64 bit?

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

I guess the best thing is to just not worry about it, an average PC could store say half a billion ints in about 4GB Ram, even if there 1 per 64 bit. But if it is a super tight memory app, then be prepared for some trickery.

I think it just boils down to speed, it's quicker to store only 1 short or int in 64 bits, than what it is to retrieve 4 shorts or 2 ints from 64 bit.
Last edited on
Topic archived. No new replies allowed.