3 ms·
double transmute_int_to_double(int x) { double result = 0; memcpy(&result, &x, sizeof(int) < sizeof(double) ? sizeof(int) : sizeof(double));
by Joker_vD 3y ago
double transmute_int_to_double(int x) {
double result = 0;
memcpy(&result, &x, sizeof(int) < sizeof(double) ? sizeof(int) : sizeof(double));
return result;
}
is not a UB, and it doesn't even necessarily touch any memory:
transmute_int_to_double:
movd xmm0, edi
ret
[0] https://godbolt.org/z/czM3eh8er https://godbolt.org/z/czM3eh8er
- kazinator 3y ago> is not UB Not by my interpretation of n3096 (April 2023 ISO C draft). > doesn't even necessarily touch any memory The abstract semantics calls for memory being touched. Data flows that go through memory in the abstract semantics can be optimized not to go through memory. UB can do anything at all.
- aw1621107 3y ago> Not by my interpretation of n3096 (April 2023 ISO C draft). What clause(s) support the claim that that example is UB? At least at first glance it looks pretty similar to the sometimes-recommended way to perform safe type-punning in C, and the only way to "directly" invoke UB via memcpy (passing pointers to overlapping objects) isn't relevant here. The only suspicious part to me is the size/number of bytes to copy, but I'm not sure that's outright UB?
- kazinator 3y agoWe have no idea whether the bytes that were copied into that object are a valid representation.
- aw1621107 3y agoAh, I didn't think of that. That being said, is there a representation for doubles that could be considered invalid? I thought all double bit patterns are interpretable as a "valid" double, even if you get NaNs.