Какова цель появления ключевого слова volatile внутри индекса массива?
Когда я просматривал cppreference, я увидел странный массив типа в параметрах функции, таких как:
void f(double x[volatile], const double y[volatile]);
Итак, какова цель появления ключевого слова volatile
внутри подстрочного индекса массива? Что он делает?
2 ответа:
Ключевое слово
Используется для объявления типа массива параметра функции.
Здесь
double x[volatile]
эквивалентноdouble * volatile x
.В cppreference говорится :
В объявлении функции, ключевое слово
volatile
может появиться внутри квадратные скобки, используемые для объявления типа массива функции параметр. он определяет тип указателя, к которому относится тип массива преобразованный. Следующие два объявления объявляют то же самое функция:void f(double x[volatile], const double y[volatile]); void f(double * volatile x, const double * volatile y);
Этот синтаксис допустим только в языке Си в параметрах функции.
В общем, это С (и только с!) функция позволяет указать любой тип квалификатора внутри скобок массива; точная стандартная цитата:
Объявление параметра в виде "массива типа" должно быть изменено на " квалифицированный указатель на type", , где квалификаторами типа (если таковые имеются) являются те, которые указаны в
[
и]
вывод типа массива . Если ключевое словоstatic
также появляется в пределах[
и]
вывод типа массива, затем для каждого вызова функции значение соответствующего фактический аргумент должен обеспечивать доступ к первому элементу массива с не меньшим числом аргументов. элементы, заданные выражением размера.(C99, §6.7.5.3, ¶7, курсив добавлен)
Это означает, что это не ограничивается только
volatile
, ноconst
иrestrict
также разрешены (см. квалификаторы типов, §6.7.3 ¶1).Суть этого хака состоит в том, чтобы позволить вам добавить квалификатор типа к параметру (не к элементу массива) и все еще сохраняют синтаксис массива для объявления; без этого синтаксиса вы вынуждены вернуться к записи его в виде указателя (что в любом случае сводится к , за исключением случая
static
, в котором AFAIK не имеет эквивалентного синтаксиса указателя).Я подозреваю, что идея заключается в том, чтобы сделать синтаксис немного менее неудобным для многомерных массивов; цитируя §6.7.5.3 *21:
void f(double (* restrict a)[5]); void f(double a[restrict][5]); void f(double a[restrict 3][5]);
Все эквивалентны, но 2 и 3 могут немного лучше передать, что это не просто указатель, а массив, и все же позволяет поместить в некотором месте квалификатор
restrict
.Кроме того, как было сказано выше, кажется, нет никакого способа иметь что-то вроде
void f(double a[restrict static 3][5]);
(который "также указывает, что аргумент, соответствующий
a
в любом вызовеf
, должен быть ненулевым указателем на первый из по крайней мере трех массивов из 5 двойников", ibidem ) с "обычный" синтаксис указателя.Тем не менее, я бы держался подальше от этого синтаксиса; он крайне неясен, редко используется (я не думаю, что мне когда - либо нужно было добавлять квалификатор типа в массив параметр - опять же, сам параметр, а не тип элемента;
restrict
- единственный вариант использования, который может иметь смысл) - и не переносится на C++ (что обычно актуально, если вы пишете библиотеку).