用于访问数组内容的可疑语法

Fli*_*ier 4 c arrays syntax

在我需要维护的一些遗留代码中,每当数组作为(void*)参数传递时,运算符都会放在数组名称前面

这是一个简单的例子:

char val = 42;
char tab[10];
memcpy(&tab, &val, 1);
Run Code Online (Sandbox Code Playgroud)

它使用gcc或clang编译,没有错误或警告.它还给出了预期的结果.

这种语法合法吗?

为什么会这样?

注意:我通常使用以下语法之一:

memcpy(tab, &val, 1);
memcpy(&tab[0], &val, 1);
Run Code Online (Sandbox Code Playgroud)

Epilog:

作为一个额外的测试,我使用一个函数取一个(char*)参数而不是(void*)

如果我尝试使用clang编译,我会收到以下警告:

warning: incompatible pointer types passing 'char (*)[10]' to parameter of type 'char *' [-Wincompatible-pointer-types]
Run Code Online (Sandbox Code Playgroud)

编辑1:在原始示例中,选项卡的大小为1个元素

为了普遍性,我只是将大小改为10.

编辑2:正如答案中提到的,memcpy取(void*)而不是(char*)

Kei*_*son 10

memcpy的参数是类型void*,而不是char*.指针类型的任何参数(不包括函数指针)都会隐式转换为void*.这是一个仅适用于的特殊情况规则void*.

鉴于声明

char tab[1];
Run Code Online (Sandbox Code Playgroud)

任一tab&tab是作为参数有效memcpy.它们评估不同类型(char*char (*)[1])的指针,但都指向相同的内存位置; 转换为void*产生相同的值.

对于实际需要char*参数的函数,只有tab有效; &tab属于错误的类型.(对于类似printf或的可变函数scanf,编译器可能无法检测到类型不匹配.)