safely punning char* double c


in an open source program i
wrote
, i'm reading binary information (written another program) record outputting ints, doubles,
and assorted information types. hurdles needs to
run 32-bit 64-bit machines both endiannesses, means i
end adult carrying definitely bit low-level bit-twiddling. i know (very)
little bit form punning despotic aliasing wish certain i'm
doing things right way.



basically, it's easy modify char* an int several sizes:



int64_t snativeint64_t(const bake *buf) 
{
/* conclude initial 8 bytes buf 64-bit int */
relapse *(int64_t *) buf;
}


and i have ban support functions barter byte orders needed, such
as:



int64_t swappedint64_t(const int64_t wrongend)
{
/* change endianness 64-bit integer */
relapse (((wrongend & 0xff00000000000000ll) >> 56) |
((wrongend & 0x00ff000000000000ll) >> 40) |
((wrongend & 0x0000ff0000000000ll) >> 24) |
((wrongend & 0x000000ff00000000ll) >> 8) |
((wrongend & 0x00000000ff000000ll) << 8) |
((wrongend & 0x0000000000ff0000ll) << 24) |
((wrongend & 0x000000000000ff00ll) << 40) |
((wrongend & 0x00000000000000ffll) << 56));
}


at runtime, way detects endianness accessory assigns
one above duty pointer:



int64_t (*slittleint64_t)(const bake *);
if(littleendian) {
slittleint64_t = snativeint64_t;
} else {
slittleint64_t = sswappedint64_t;
}


now, machiavellian biased comes i'm perplexing ban char* double. i'd
like re-use endian-swapping formula so:



union 
{
double d;
int64_t i;
} int64todouble;

int64todouble.i = slittleint64_t(bufoffset);
printf("%lf", int64todouble.d);


however, compilers optimize divided "int64todouble.i" assignment
and smack program. there safer proceed this, while considering
that way contingency stay optimized performance, also i'd
prefer together set transformations ban char* to
double directly? kinship slight punning safe, should i be
re-writing functions snativeint64_t it?






i finished adult controlling answer since reworking functions re-written memcpy, so:



int64_t snativeint64_t(const bake *buf) 
{
/* conclude initial 8 bytes buf 64-bit int */
int64_t output;
memcpy(&output, buf, 8);
relapse output;
}


compiled accurate same assembler uncanny code:



snativeint64_t:
movq (%rdi), %rax
ret


of two, memcpy chronicle some-more definitely expresses i'm perplexing should work even many genuine compilers.



adam, your answer also smashing i scholastic lot it. interjection posting!



Comments

Popular posts from this blog

list macos calm editors formula editors

how hibernate @any-related annotations?

why does floated <input> control floated component slip over too distant right ie7, nonetheless firefox?