О практическом преимуществе возможности "гарантии" размера массива в C99 в параметрах функции? - PullRequest
4 голосов
/ 11 июля 2020

C99 представила новую нотацию аргумента функции, в которой ключевое слово static может использоваться для указания того, что аргумент имеет как минимум N элементов.

6.7.6.3 Деклараторы функций, p7

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

Например,

void func(int x[static 10])
{
    /* something */
}

говорит, что x имеет не менее 10 элементов. Но это не ограничение, и поэтому компилятор не обязан выдавать диагностику c.

Обоснование C99 по этому поводу:

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

В C99 использование ключевого слова stati c в:

void fadd(double a[static 10], const double b[static 10]) {
    int i;
    for (i = 0; i < 10; i++) {
        if (a[i] < 0.0)
            return;
        a[i] += b[i];
    }
    return;
}

гарантирует, что оба указателя a и b обеспечивают доступ к первому элементу массива, содержащего не менее десяти элементов. Ключевое слово static также гарантирует, что указатель не равен NULL и указывает на объект соответствующего действующего типа.

Обоснование, похоже, предлагает более строгие гарантии, чем те, которые указаны в стандарте C. *

На основе этих фактов:

  • Существуют ли какие-либо практические системы, в которых это дает «значительные преимущества», как указано в обосновании?
  • Почему стандарт C делает нет таких гарантий (как в обосновании C99), которые могли бы мотивировать введение этой функции в первую очередь?

(Очевидно, что лучшую диагностику времени компиляции можно было бы использовать только один раз, но это не значит " значительное преимущество »и не помогает оптимизациям, как предполагалось. Кроме того, компиляторы всегда могут выполнить диагностику, если они обнаружат потенциальное разыменование нулевого указателя без такой формальной функции).

1 Ответ

2 голосов
/ 11 июля 2020

Я не совсем понимаю ваш вопрос, но думаю, вы можете быть сбиты с толку, что влечет за собой отсутствие «ограничения» здесь. Это не ограничение, и компилятор не обязан выдавать диагностику c, потому что компилятор не обязательно может видеть определение функции в точке (ах) ее вызова (ов). Гарантия размера массива static является свойством функции определение , а не функцией тип / объявление . Это может быть вызвано различными причинами, наиболее вероятными из которых является желание не делать объявления с / без несовместимых типов функций.

К сожалению, это ограничивает возможность использования функции только для оптимизации, а не проверка правильности , за исключением случаев, когда компилятор (или компоновщик) может видеть несоответствие. «Преимущество» этой функции в том, что компилятор может выполнять оптимизацию, читающую индексы, которые не будут прочитаны на абстрактной машине. Например, в:

int foo(int a, int b[static 1])
{
    if (!a) return 0;
    else return a & *b;
}

ветку можно оптимизировать.

...