在一些遗留代码中我必须维护,&每当数组作为(void *)arguments
传递时,运算符都会放在数组名称前面这是一个简单的例子:
char val = 42;
char tab[10];
memcpy(&tab, &val, 1);
它使用gcc或clang编译,没有错误或警告。它也给出了预期的结果。
这种语法合法吗?
为什么会这样?
注意:我通常使用以下语法之一:
memcpy(tab, &val, 1);
memcpy(&tab[0], &val, 1);
Epilog:
作为一个额外的测试,我使用了一个函数,取一个(char *)参数而不是(void *)
如果我尝试使用clang编译,我会收到以下警告:
warning: incompatible pointer types passing 'char (*)[10]' to parameter of type 'char *' [-Wincompatible-pointer-types]
编辑1: 在原始示例中,选项卡的大小为1个元素
为了普遍性,我只是将大小更改为10.
编辑2: 正如答案中提到的,memcpy采用(void *)而不是(char *) 的
答案 0 :(得分:10)
memcpy
的参数属于void*
,而非char*
。指针类型的任何参数(不包括函数指针)都会隐式转换为void*
。这是一个特殊情况规则,仅适用于void*
。
鉴于声明
char tab[1];
tab
或&tab
作为memcpy
的参数有效。他们评估不同类型的指针(char*
和char (*)[1]
),但都指向相同的内存位置;转换为void*
会产生相同的值。
对于实际需要char*
参数的函数,只有tab
有效; &tab
的类型错误。 (对于像printf
或scanf
这样的可变函数,编译器可能无法检测到类型不匹配。)