-
-
Notifications
You must be signed in to change notification settings - Fork 262
Description
It's possible this comes down to default compiler flags. Nevertheless, I am trying to pick apart how C types are being cast in order to demonstrate fast vector operations on a basic microcontroller without needing extra range checking and have found a handful of frustrations, the two most notable:
- casting 0x8000 from a int16_t (-32768) to a uint32_t results in 2^32 − 32768 (unwanted)
- casting 0x8000 from a int16_t to a uint16_t and then (unwanted) to uint32_t results in 32768 (wanted)
Here is the bare example:
#include <iostream>
#include <cstdint>
int main() {
int16_t a = (int16_t)0x8000;
std::cout << a << std::endl;
std::cout << (uint32_t)a << std::endl;
std::cout << (uint32_t)(uint16_t)a << std::endl;
}with output (in clang, gcc, and MSVC)
-32768
4294934528
32768…and the corresponding Insights output:
#include <iostream>
#include <cstdint>
int main()
{
int16_t a = static_cast<short>(32768);
std::cout.operator<<(a).operator<<(std::endl);
std::cout.operator<<(static_cast<unsigned int>(a)).operator<<(std::endl);
std::cout.operator<<(static_cast<unsigned int>(a)).operator<<(std::endl);
return 0;
}It is clear the last two cout lines will have the same output, but here it is:
-32768
4294934528
4294934528For my application, this doesn't end up having any ill side effect other than setting the OV flag on x86 as any other number casts correctly, although I don't know that every architecture would have the same method of casting and would also be free of side effects. Thus, I wanted to know exactly how each cast was occurring and which argument type of cout is called, and if there is a good way to force the cast to be always correct with a single function or cast.
If I insert another static_cast<unsigned short>(...) in the third line, the output matches again, so it's possible two static_cast should be chained but one is being cast (hehe) away
(reinterpret_cast on its own is forbidden by some compilers, and changing the code to allow the non-static casts makes the demo harder to understand.)