Яка мета статичного ключового слова в параметрі масиву функції типу "char s [static 10]"?


144

Під час перегляду якогось вихідного коду я натрапив на таку функцію:

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

З деяким експериментом здається, що там можуть з’явитися і інші кваліфікуючі:

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

Виявляється, що класифікатори дозволені всередині, [ ]коли масив оголошено як параметр функції. Що вони роблять? Чому це відрізняється від параметрів функції?

Відповіді:


127

Перша декларація повідомляє компілятору, що someArrayмає принаймні 100 елементів. Це можна використовувати для оптимізації. Наприклад, це також означає, що someArrayніколи NULL.

Зауважте, що стандарт C не вимагає від компілятора діагностувати, коли виклик функції не відповідає цим вимогам (тобто, це мовчазна невизначена поведінка).

Друга декларація просто оголошує someArray(не someArrayелементи!) Як const, тобто писати не можна someArray=someOtherArray. Це те саме, як якщо б параметр був char * const someArray.

Цей синтаксис може бути використаний лише у внутрішній []деклараторі масиву у списку функціональних параметрів; це не мало б сенсу в інших контекстах.

Стандартний текст, який охоплює обидва вищезазначені випадки, міститься в C11 6.7.6.3/7 (було 6.7.5.3/7 у C99):

Декларація параметра як "" масив типу "" має бути скоригована на "кваліфікований покажчик на тип", де класифікаторами типу (якщо такі є) є ті, які вказані в [і ]виведення типу масиву. Якщо статичне ключове слово також з’являється в межах [і ]виведення типу масиву, то для кожного виклику функції значення відповідного фактичного аргументу має забезпечити доступ до першого елемента масиву, що має принаймні стільки елементів, як зазначено в вираз розміру


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 є примітка, в якій згадується передбачуване значення, і все. Сумніваюся, що ми можемо на це покластися. Крім того, все це не є частиною підпису функції, тому не дуже багато ми виконуємо через неї.
Північна мейнфрейм

5
Це посилання, схоже, загнило, це те, на що він вказував? pic.dhe.ibm.com/infocenter/zos/v1r12/…
Ross Aiken

13
@NordicMainframe: Минув уже деякий час, але поточна версія clangтепер правильно попереджає, коли ви намагаєтесь передати відомий NULL аргумент функції з [static 1]декларацією параметра.
dreamlax

1
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功if (!someArray) { somecode... }можна було видалити
ММ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.