在uint8_t [8]&之间安全转换通过铸造uint64_t? [英] Convert safely between uint8_t[8] & uint64_t via cast?

查看:160
本文介绍了在uint8_t [8]&之间安全转换通过铸造uint64_t?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前的操作方式(我希望摆脱 memcpy 调用):

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

假设 integer 数组长度始终是8的倍数(总共64位分配),考虑到编译器的填充/对齐问题,是否可以直接转换?

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?

推荐答案

如果您正在寻求优化,则绝对无需避免或替换 memcpy()调用.每个现代的优化编译器都不会发出调用,而是生成等效的汇编代码.当没有给出与优化相关的选项时,较新的GCC和Clang版本甚至会执行此操作.可以使用 -fno-builtin 禁用该行为.

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;
}

例如,针对x86_64的GCC 4.8.1产生:

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

以及 -O3 :

u8tou64:
    mov rax, QWORD PTR [rdi]
    ret

John Regehr的

此博客帖子得出了相同的结论( c5()调用 memcpy()):

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

我认为 c5 是最简单的代码一批功能,因为它不会造成混乱的转移,而且完全,完全,显然没有可能出现的并发症源自混乱的工会规则和严格的别名.它几年前当我成为类型修剪的首选成语时发现编译器可以查看 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.

诸如使用并集或按位运算之类的替代方法可能不会导致最佳代码(且外观不错),或者无法在ISO C90或C ++中使用(这也包括GCC的 __ may_alias __ 属性,在评论部分).

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).

这篇关于在uint8_t [8]&amp;之间安全转换通过铸造uint64_t?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆