4

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

这是一个简单的例子:

char val = 42;
char tab[10];
memcpy(&tab, &val, 1);

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

这种语法合法吗?

为什么这行得通?

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

memcpy(tab, &val, 1);
memcpy(&tab[0], &val, 1);

结语:

作为一个额外的测试,我使用了一个带有 (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*)

4

1 回答 1

10

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

鉴于声明

char tab[1];

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

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

于 2013-10-19T18:53:49.813 回答