Какова цель ключевого слова static в параметре массива функции типа «char s [static 10]»?

148

Просматривая исходный код, я наткнулся на такую ​​функцию:

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

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

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

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

мечта
источник

Ответы:

130

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

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

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

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

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

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

Скандинавский мэйнфрейм
источник
35
По этой теме: интересно, следует ли считать его предпочтительным использовать int foo(struct bar [static 1]);вместо int foo(struct bar *);подписи для функций, которые не принимают указатели NULL. (Я знаю, что у gcc есть альтернативный нестандартный синтаксис для пометки таких функций, чтобы компилятор мог выдавать предупреждения ..)
R .. GitHub ОСТАНОВИТЬ ПОМОЩЬ ICE
2
Я только что проверил gcc и clang и не предполагаю, что someArray всегда не равен нулю, когда я прошу их сравнить с 0. Также мне трудно найти точное предложение в C99, которое его определяет. В 6.7.5.3-21 есть примечание, в котором упоминается предполагаемое значение, и все. Сомневаюсь, что на это можно рассчитывать. Более того, все это не является частью сигнатуры функции, поэтому мы мало что можем реализовать через нее.
Nordic Mainframe
5
Эта ссылка, кажется, сгнила, это то, на что она указывала? pic.dhe.ibm.com/infocenter/zos/v1r12/…
Росс Эйкен,
13
@NordicMainframe: Прошло некоторое время, но текущая версия clangтеперь правильно предупреждает, когда вы пытаетесь передать аргумент с известным NULL в функцию с [static 1]объявлением параметра.
dreamlax
1
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功if (!someArray) { somecode... }может быть удален
MM