Сомнительный синтаксис для доступа к содержимому массива

В некотором устаревшем коде, который я должен поддерживать, операторы & ставятся перед именами массивов всякий раз, когда массивы должны передаваться как (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*)

1 ответ

Решение

memcpyпараметры имеют тип void*не char*, Любой аргумент типа указателя (кроме указателей на функции) неявно преобразуется в void*, Это правило особого случая, которое применяется только к void*,

Учитывая декларацию

char tab[1];

или tab или же &tab действителен в качестве аргумента memcpy, Они оценивают указатели разных типов (char* а также char (*)[1]), но оба указывают на одну и ту же область памяти; преобразование либо в void* дает то же значение.

Для функции, которая на самом деле требует char* только аргумент tab является действительным; &tab имеет неправильный тип. (Для переменной функции, такой как printf или же scanfвозможно, компилятор не сможет обнаружить несоответствие типов.)

Другие вопросы по тегам