Что это за странные размеры массивов [*] и [static] в C99?

По-видимому, следующие прототипы функций действительны в C99 и C11:

void foo(int a[const *]);

void bar(int a[static volatile 10]);

Какова цель этих странных индексных обозначений *, static и квалификаторов CV?

Помогают ли они отличать статически типизированные массивы от массивов переменной длины? Или они просто синтаксический сахар?


person Kerrek SB    schedule 09.07.2013    source источник
comment
статический: stackoverflow.com/questions/3430315/   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 10.05.2016
comment
звездочка: stackoverflow.com/questions/17371645/parameter-of-a- функция   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 10.05.2016


Ответы (1)


static в деклараторе массива параметров

 void f(int a[static 10]);

static здесь указывает, что параметр a является указателем на int, но что объект массива (где a является указателем на его первый элемент) имеет по крайней мере 10 элементов.

Тогда компилятор имеет право предположить, что аргумент f не является NULL, и поэтому он может выполнить некоторые оптимизации. gcc в настоящее время оптимизация не выполняется (источник):

«Информация, предоставляемая статическими деклараторами массива параметров, не используется для оптимизации. Возможно, имеет смысл использовать ее в будущем в сочетании с работой над предварительной выборкой».

квалификатор в деклараторе массива параметров

void g(int a[cvr 10]);

внутри g a — указатель cvr на int (cvr — это квалификатор const, volatile или restrict). Например, с const это означает, что a является указателем const на int (т. е. тип int * const).

Итак, объявление параметра:

T param[cvr e] 

то же самое, что и объявление параметра:

T * cvr param

* в деклараторе массива параметров

void h(int a[*]);

[*] в объявлении параметра формального массива в объявлении функции (которое не является частью определения функции) указывает, что формальный массив является массивом переменной длины.

person ouah    schedule 09.07.2013
comment
Чем это полезно? Кажется, я не получаю никакой значимой диагностики, когда вызываю функции с неправильным типом массива (неправильный размер или неправильный VLAness). Получаете ли вы sizeof поддержку для [*]? - person Kerrek SB; 10.07.2013
comment
@KerrekSB C не требует диагностики, и я думаю, что компиляторы не выдают предупреждения, потому что эта функция используется очень редко. - person ouah; 10.07.2013
comment
@KerrekSB для sizeof с int (*)[*], например с gcc, я получаю '[*]', не разрешенный в области, отличной от области прототипа функции - person ouah; 10.07.2013
comment
@KerrekSB, sizeof для [*] невозможно по той простой причине, что это разрешено только в объявлениях, а не в определениях. Для VLA в качестве параметров функции выражение размера оценивается так, как если бы оно было помещено в начало тела функции. [*] — это заполнитель для выражения в объявлении для тех случаев, когда кто-то не знает (или не хочет) сделать это выражение видимым в интерфейсе. Внутри функция sizeof работает как положено, только у вас нет первого измерения, как всегда для параметров массива. - person Jens Gustedt; 10.07.2013