2010-08-07 4 views
117

При просмотре некоторый исходный код, который я наткнулся на функцию, как это:Какова цель статического ключевого слова в параметре массива функции типа "char s [static 10]"?

void someFunction(char someArray[static 100]) 
{ 
    // do something cool here 
} 

некоторых экспериментов оказывается другие классификаторы могут появиться там тоже:

void someFunction(char someArray[const]) 
{ 
    // do something cool here 
} 

Оказывается, что отборочные разрешается только внутри [], когда массив объявлен как параметр функции. Что они делают? Почему он отличается от параметров функции?

ответ

101

Первая декларация сообщает компилятору, что someArray is не менее 100 элементов длиной. Это можно использовать для оптимизации. Например, это также означает, что someArray никогда не имеет значения NULL.

Обратите внимание, что C-стандарт не требует, чтобы компилятор диагностировал, когда вызов функции не отвечает этим требованиям (т. Е. Это бесшумное неопределенное поведение).

Вторая декларация просто объявляет someArray (не элементы someArray) как const, то есть вы не можете написать someArray=someOtherArray. Это то же самое, что и параметр char * const someArray.

Этот синтаксис можно использовать только внутри самого внутреннего [] объявления класса в списке параметров функции, это не имеет смысла в других контекстах.

Стандартный текст, который охватывает оба указанных выше случаев, в С11 6.7.6.3/7 (был 6.7.5.3/7 в C99):

Декларация параметра как «» массива типа '' должны быть скорректированы на «квалифицированный указатель на тип», где квалификаторы типа (если они есть) - это те, которые указаны в [ и ] вывода типа массива. Если ключевое слово static также появляется в пределах [ и ] вывода типа массива, то для каждого вызова функции значение соответствующего фактического аргумента должно обеспечивать доступ к первому элементу массива с по меньшей мере таким количеством элементов , что и указанный выражением размера.

+30

Об этой теме: Интересно, следует ли считать предпочтительным использование 'int foo (struct bar [static 1]);' вместо 'int foo (struct bar *);' как сигнатура для функций, которые не принимайте указатели NULL. (Я знаю, что gcc имеет альтернативный нестандартный синтаксис для обозначения таких функций, чтобы компилятор мог дать предупреждения ..) –

+2

Я только что проверил gcc и clang и не предполагаю, что someArray всегда не имеет значения null, когда я прошу их сравнивать с 0. Также я изо всех сил пытаюсь найти точный пункт в C99, который его определяет. В 6.7.5.3-21 есть примечание, в котором упоминается предполагаемый смысл, и все. Я сомневаюсь, что мы можем положиться на это. Кроме того, все это не является частью сигнатуры функции, поэтому там не так много, что мы обеспечиваем ее. –

+5

Эта ссылка, похоже, прогнила, это то, на что она указывала? http://pic.dhe.ibm.com/infocenter/zos/v1r12/index.jsp?topic=%2Fcom.ibm.zos.r12.cbclx01%2Fparam_decl.htm –

Смежные вопросы