为什么memcpy需要const void指针?

Cla*_*nda 2 c

我想使用memcpy在一个可能包含任意类型的数组中进行'类型不可知交换'.为什么需要const src指针?

我写了自己的版本:

void copyBytes(char *x, char *y, int howMany){
  int i;
  for(i = 0; i<howMany; i++){
    *(x+i) = *(y+i);
  }
}
Run Code Online (Sandbox Code Playgroud)

我的版本有问题吗?

asv*_*kau 7

我的版本有问题吗?

我会这么说的.这是批评.

void copyBytes(char *x, char *y, int howMany)
Run Code Online (Sandbox Code Playgroud)

首先是你的指针char *,这意味着除了char *需要显式转换之外的任何指针类型.您应该使用void *,隐式转换指针类型.

uint16_t a, b;

copyBytes(&a, &b, sizeof(a));  // &a and &b are uint16_t*, not char*.
Run Code Online (Sandbox Code Playgroud)

第二,来源,y不是const,这意味着如果您通过const来源,您将收到警告.

char buf[512];
const char str[] = "Hello world";  // Contents of string are constant.
copyBytes(buf, str, sizeof(str));  // With your code, this produces a warning.
Run Code Online (Sandbox Code Playgroud)

第三,howMany签名,意味着您可以传递负值.

我会推荐这样的签名(顺便说一句,这非常相似memcpy):

void copyBytes(void *x, const void *y, size_t howMany)
Run Code Online (Sandbox Code Playgroud)

第四个批评... libc memcpy可能会更好地进行优化,使用大于字节的单位,特定于平台的性能技巧(例如:内联汇编,x86上的SSE)等等.还有memmove更好的指定行为.缓冲区重叠.

总结:为了学习的目的,自己编写这些例程是很好的,但是通常你会更好地使用C库.


AnT*_*AnT 6

"要求"?"要求"是一个错误的词.memcpy并不需要一个constSRC指针.它允许一个constSRC指针.允许constsrc指针是一个较弱的规范,然后需要一个非const src指针.它扩展了功能的适用性,而不是限制它.

需要一个非const src指针会限制它的适用性memcpy- 你将无法将指针传递const给你的函数(除非你使用丑陋的演员).你为什么要引入这样的要求?memcpy不修改src数据,因此允许将常量数据用作src 是完全合乎逻辑的memcpy.这就是为什么memcpy将src指针声明为const.

在这种情况下,"require"一词实际上适用于您的版本.您的版本需要非常量指针作为src指针.而且由于这个额外的(并且完全不需要的)要求,您的版本不太适用memcpy.例如

const char src_data[3] = { 1, 2, 3 };
char dst_data[3];

memcpy(dst_data, src_data, sizeof dst_data);    // Works
copyBytes(dst_data, src_data, sizeof dst_data); // Doesn't even compile
Run Code Online (Sandbox Code Playgroud)