Какви са тези странни размери на масиви [*] и [статични] в 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
static: 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)


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

 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