【问题标题】:implementation of memcpy functionmemcpy函数的实现
【发布时间】:2023-03-21 14:59:01
【问题描述】:

我看了 http://www.opensource.apple.com/source/xnu/xnu-2050.24.15/libsyscall/wrappers/memcpy.c

并且不明白以下内容:

1-

里面

void * memcpy(void *dst0, const void *src0, size_t length) {
    char *dst = dst0;
    const char *src = src0;

行:

if ((unsigned long)dst < (unsigned long)src) {

我们如何将 dst 转换为 unsigned long ?这是一个指针!

2- 为什么他们有时喜欢向前复制,有时喜欢向后复制??

【问题讨论】:

  • 可能是因为函数的创建者知道在XNU平台上,类型unsigned long和指针大小一样?其他地方可能有一些静态断言可以确保情况确实如此。
  • 为了提高这个问题的质量,最好有dstsrc 的声明。这样问题就很清楚了,而无需按照提供的链接进行操作(但可能会随着时间的推移而改变)。
  • @alk 好主意。我将其添加到问题中。
  • 指针是地址,地址可以表示为unsigned long
  • @alk - 如果你比较“不兼容的指针”,你会得到编译器的抱怨。在我看来,最简洁的编码方式是if((void*)dst &lt; (void*)src)。无需知道指针有多大,没有编译器投诉(任何指针都可以转换为void *)。

标签: c memcpy


【解决方案1】:

你是对的,这个实现是不可移植的,因为它假设一个指针将适合unsigned long。标准不保证这一点。

此实现的正确类型应该是uintptr_t,它保证适合指针。

【讨论】:

  • 请注意,uintptr_t 位于 stdint.h 中,需要现代 C 编译器(C99 或更高版本)。
  • 奇怪的是,同一个函数后来确实将指针转换为uintptr_t
【解决方案2】:

当比较void*char*指针时,编译器会给出警告(gcc -Wall):

warning: comparison of distinct pointer types lacks a cast

我想开发人员决定“让警告消失” - 但正确的做法是使用 void* 演员表(可移植):

if((void*) dst < (void*) src) {

至于第二点 - 正如所指出的,您必须注意重叠的内存位置。想象以下 8 个字符在连续的内存位置:

 abcdefgh

现在我们要复制这个“向右 3”。从 a 开始,我们会得到(从左到右的副本):

abcdefgh
abcaefgh
   ^
abcabfgh
   ^^
abcabcgh
   ^^^

等等,直到你最终得到

abcabcabcab
   ^^^^^^^^

当我们想要得到时

abcabcdefgh

从另一端开始,我们不会覆盖仍需复制的内容。当目的地在源的左侧时,您必须朝相反的方向进行。当源和目标之间没有重叠时,你做什么都没关系。

【讨论】:

    猜你喜欢
    • 2013-10-11
    • 1970-01-01
    • 2013-10-12
    • 2018-12-31
    • 2021-12-28
    • 2021-07-16
    • 2015-02-26
    • 1970-01-01
    • 2014-02-08
    相关资源
    最近更新 更多