Как я могу ограничить параметры массива в C (не делая их указателями)?

Мотивация

Параметры массива могут совпадать друг с другом, и компилятор должен тщательно учитывать эту возможность. Так, например: GodBolt

int foo(int a[10], int b[10]) {
    a[0] += b[0];
    return a[0] + b[0];
}

int bar(int *a, int *b) {
    a[0] += b[0];
    return a[0] + b[0];
}

int baz(int * __restrict a, int * __restrict b) {
    a[0] += b[0];
    return a[0] + b[0];
}

скомпилированный код для foo() должен быть похож на код bar(), а не на код baz().

Вопрос

Я хочу использовать параметры массива для своей функции - возможно, даже многомерные массивы (а не массивы указателей; те, которые вы объявляете с помощью пары квадратных скобок и распадаетесь на простые одноуровневые указатели на первый элемент). И я также хочу, чтобы компилятор предполагал, что псевдонимов нет, т. е. я хочу пометить параметры моего массива как restrict.

Как я могу сделать это в C? А если я не могу - почему?

Я не следую. Вы не можете передать массив функции в C. В языке нет способа выразить это. Когда вы указываете аргумент функции, имеющий тип массива, он автоматически преобразуется в указатель на первый элемент массива, как и почти во всех других контекстах выражений. Функция получает указатель, и вы можете объявить этот указатель restricted, если хотите.

John Bollinger 04.09.2024 16:52

Вы же понимаете, что (1) и (2) полностью эквивалентны, верно? Даже если окажется, что это невозможно с помощью синтаксиса массива (неважно, очевидно, что это возможно, см. ссылку выше), вы все равно можете использовать int (*__restrict a)[42] вместо int a[10][42], чтобы добиться того же самого.

HolyBlackCat 04.09.2024 16:52

@JohnBollinger: я не собираюсь передавать массив по значению. Это «на самом деле» просто переданный указатель. Вопрос в том, как объявить это ограничение для параметра массива?

einpoklum 04.09.2024 16:52

Первый комментарий ссылается на ответ, но на самом деле вопрос касается только синтаксического сахара.

Eugene Sh. 04.09.2024 16:53

@Mat: Кажется, это ответ. Отметил это как обман.

einpoklum 04.09.2024 16:54

Не нужно пугающих цитат. Это действительно просто указатель. Это возвращает меня к непониманию вопроса. Как вы думаете, чем эта ситуация отличается от любой другой ситуации с параметром указателя, которая представляет сложность для restrict?

John Bollinger 04.09.2024 16:54

@JohnBollinger: Как сказал Юджин Ш - только синтаксис. Это не интуитивно понятно.

einpoklum 04.09.2024 16:56
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
8
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете поместить квалификаторы в самое левое объявление массива параметра (т. е. в ту часть, которая преобразуется в указатель):

int foo(int a[restrict 10], int b[restrict 10]) {
    a[0] += b[0];
    return a[0] + b[0];
}

Кажется, это действительно ответ. Но уже есть вопрос с похожим ответом, поэтому мне интересно, голосовать за него и принимать или нет. Ах, что ж, давайте просто сделаем это.

einpoklum 04.09.2024 16:57

Поскольку я не понимаю значения атрибутов OP для использования здесь синтаксиса массива вместо синтаксиса указателей, кажется разумным отметить, что, если static не входит в число заданных квалификаторов, числовое измерение в таком объявлении параметра не является семантически значимым.

John Bollinger 04.09.2024 17:06

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