I was trying to understand std::variant:
#include <cstdint>
#include <variant>
std::variant<int64_t, double> v;
I wanted to assign an int64_t variant: v = 5L;
That compiles on x86_64 because int64_t is long. But it does not compile on arm, because int64_t is long long. The type deduction has now two equal choices between int64_t and double to convert my number to, so it declines. With variant<int64_t, string> I wouldn't even have noticed the conversion, because then there is only one available and the compiler would have accepted it.
Similar issue with: v = 5LL;
Now arm / 32 bit is fine, but x86_64 not anymore.
I get this compiling on both platforms but this is (sometimes) a type conversion with potential side-effects I am not able to foresee: v = int64_t(5LL);
. Without the LL I wouldn't even be able to express values outside 32bit int.
The INT64_C macro seems to be the most portable and safest way to express this: v = INT64_C(5);
But this not nice to read and write anymore.
Is there a similar literal suffix like L/LL for int64_t that is portable?
int64_t i = (int64_t)5;
. (And it's fully portable and resolved at compile time.) – Explanationdynamic_cast
excluded to which even I got used) it does the intended... ;-) – Explanationv = 5L
should always compile, becausedouble
isn't a candidate for assignment (in the example withv4
). This seems to be because it is a narrowing conversion solong&& t = 5l; double x[] = { static_cast<long&&>(t) };
doesn't compile – Mongolian