在学习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