c/c++语言开发共享Memcpy实现,严格别名

在学习c的同时,我实现了自己的memcpyfunction。 我在函数中使用了更宽泛的类型( uint32_t )。 (为简单起见,该函数仅限于4的倍数且数据正确对齐的类型)

 void memcpy4( void* dst , void* src , int size ) { size /= 4; for ( int i = 0 ; i < size ; i++ ) ((uint32_t*)dst)[i] = ((uint32_t*)src)[i]; } 

我做了关于类型惩罚和严格别名的阅读,我相信上面的function打破了规则。 正确的实现是这样的,因为你可以使用char:

 void memcpy4( void* dst , void* src , int size ) { for ( int i = 0 ; i < size ; i++ ) ((char *)dst)[i] = ((char *)src)[i]; } 

我试图通过一个联盟进行一些投射,但结果certificate它也是无效的。

如何用更广泛的类型实现这样的function而不破坏严格的别名规则?

    使用多个单字节副本实现memcpy方法是使用非标准的C.

    标准C不支持使用非字符类型实现memcpy

    Quality C实现提供了一个优化的memcpy实现,它使用多个单字节副本执行高效复制,但它们使用特定于实现的代码来执行此操作。 他们可以通过使用-fnostrict-aliasing等开关编译memcpy实现来告诉编译器,在代码中违反别名规则,依靠特定C实现的已知function来确保代码能够正常工作(如果你编写编译器,你可以设计它,以便你的memcpy的实现工作),或通过汇编语言编写memcpy

    此外,C实现可以优化memcpy调用,它们出现在源代码中,通过直接指令替换它们来执行操作或者只是更改程序的内部语义。 (例如,如果将a复制到b ,编译器可能根本不执行复制,但可能只是从后续代码访问a位置加载b 。)

    要在违反别名规则的情况下实现您自己的专用复制操作,请使用-fnostrict-aliasing编译,如果您使用的是GCC或Clang。 如果您使用的是其他编译器,请检查其文档以获取禁用别名规则的选项。 (注意:我使用的Apple的GCC默认禁用严格别名并接受-fstrict-aliasing但不接受-fnostrict-aliasing 。我假设非Apple GCC接受-fnostrict-aliasing 。)

    如果您正在使用一个好的C实现,您可能会发现memcpy4四字节复制实现的效果不如本机memcpy ,具体取决于具体情况。

    除了假设sizeof(uint32_t) == 4 ,该行

     size /= 4; 

    在你的第一个实现是完全错误的:

    除法是整数除法,因此它有效地计算floor(size/4) 。 因此,如果原始size不能被4整除,则源中的1到3个字节将不会被复制到目标。

    需要了解更多c/c++开发分享Memcpy实现,严格别名,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享Memcpy实现,严格别名相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/979890.html

      (0)
      上一篇 2021年12月13日
      下一篇 2021年12月13日

      精彩推荐