C++ is doing implicit integer promotion of integer variables with types smaller than int, and that promotion converts those values (of the operands of the +) to int (gross generalization yeah yeah).
So the result on g++ amd64 will be 100000 (as you would expect) if int is more than 16 bits (nowadays it is), even WITH `(uint16_t(50000) + uint16_t(50000))`.
I've also tried it in MSVC 2010 and it says the result of `std::cout << (uint16_t(50000) + uint16_t(50000)) << std::endl` is 100000 (both on win32 and on x64).
Try it on an arduino and you will get 34464 (with g++ targeting 8 bit atmel).
Think you want implicit integer promotion in a systems language? You really don't. They are an unnecessary language feature.
Also, the article is only tangentially about that--that's just an intro. The actual body makes very good points, and I think it's more than a little tongue-in-cheek :)
uint16(50_000) * uint16(50_000) is uint32(2_500_000_000), which turns out to be int32(-1_794_967_296), the garbage result the author cites.
If int was 16-bit (which it is allowed to be), no integer promotion would take place, and the result would be 50000^2 mod 2^16 = 63744.
FTFY
Multiplication of intX_t by intX_t should produce int2X_t which is btw is what actually happens in hardware! And detection of overflow of addition/multiplication in a sane language should not require ridiculous algebraic acrobatics that involve additional additions/multiplications (or a division, yeah, I've seen that too).
template<size_t N> operator*(int<N>, int<N>) -> int<2*N>
instead of template<size_t N> operator*(int<N>, int<N>) -> int<min(numeric_limits<int>::width, N)>
? Why or why not?But again, all your arguing about "numbers should be closed under arithmetic operations just as they are in C/C++" is kinda pointless because in C/C++, they are not! When you add/multiply two signed char's, or two shorts, you get an int, not a signed char/short, so only ints and longs are actually closed under arithmetic operations. Whoops!