Convert safely between uint8_t[8] & uint64_t via cast?

放肆的年华 提交于 2021-01-27 17:00:48

问题


The way I'm currently doing it (I'd prefer to get rid of the memcpy call):

uint64_t integer;
uint8_t string[8];
...
memcpy(&integer, &string, 8); //or swap the parameters

Assuming integer array length to always be a multiple of 8 (64 bits total allocation) is a straight cast possible given compiler padding / alignment concerns?


回答1:


There is absolutely no need to avoid or replace a memcpy() call if you're striving for optimization. Every modern optimizing compiler won't emit a call and generate equivalent assembly code instead. Newer GCC and Clang versions even do this when no optimization related options were given. That behavior can be disabled with -fno-builtin by the way.

You can verify this by yourself by using the C++ Compiler Explorer (or locally with -S, of course):

#include <string.h>
#include <stdint.h>

uint64_t
u8tou64(uint8_t const u8[static 8]){
  uint64_t u64;
  memcpy(&u64, u8, sizeof u64);
  return u64;
}

For example, GCC 4.8.1 targeting x86_64 produces:

u8tou64:
    push    rbp
    mov rbp, rsp
    mov QWORD PTR [rbp-24], rdi
    mov rax, QWORD PTR [rbp-24]
    mov rax, QWORD PTR [rax]
    mov QWORD PTR [rbp-8], rax
    mov rax, QWORD PTR [rbp-8]
    pop rbp
    ret

And with -O3:

u8tou64:
    mov rax, QWORD PTR [rdi]
    ret

This blog post by John Regehr comes to the same conclusion (c5() calls memcpy()):

In my opinion c5 is the easiest code to understand out of this little batch of functions because it doesn’t do the messy shifting and also it is totally, completely, obviously free of complications that might arise from the confusing rules for unions and strict aliasing. It became my preferred idiom for type punning a few years ago when I discovered that compilers could see through the memcpy and generate the right code.

Alternatives like using a union or bitwise operations may not result in optimal (and decent looking) code or can't be used in ISO C90 or C++ (this also includes GCC's __may_alias__ attribute which is mentioned in the comment section).



来源:https://stackoverflow.com/questions/29195075/convert-safely-between-uint8-t8-uint64-t-via-cast

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!