GCC: Индекс статического массива в аргументе функции не вызывает никакого предупреждения - PullRequest
0 голосов
/ 28 декабря 2018

Я пытаюсь понять использование ключевого слова «static» в качестве индекса массива в объявлении функции на языке C.

После прочтения этой статьи я пытался объявить такоефункции и целенаправленно передавая ей слишком короткий массив:

#include <stdio.h>
#include <stdlib.h>


void print_string10(char string10[static 10]) {

// Should trigger a warning if the argument is NULL or an array of less than 10 elements

    printf("%s\n",string10);

}

int main(void) {

    char short_string[] = "test";

    print_string10(short_string); // should trigger a warning as the string is 5 long

    return EXIT_SUCCESS;
}

Компиляция с clang, как в статье, выдает предупреждение, но gcc -Wall -Werror - нет, она компилируется и работает нормально.

Я не смог найти объяснения, это нормальное поведение для GCC, чтобы пропустить это предупреждение?

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Почему не нужно , чтобы вызвать предупреждение, из-за раздела стандарта, в котором это происходит - 6.7.6.3p7 :

Семантика

[...]

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

Появляется в разделе семантика .Соответствующая реализация требуется только для диагностики тех, которые появляются в ограничениях .Даже когда он не диагностирует нарушение здесь, он может использовать знание ключевого слова static, чтобы сделать вывод, что аргумент не равен нулю, и что при циклическом развертывании и других оптимизациях может ожидаться массив, который будет иметь по крайней мере столько же элементов.


Также обратите внимание, что пример 5 там говорит, что

   void   f(double      (* restrict a)[5]);
   void   f(double      a[restrict][5]);
   void   f(double      a[restrict 3][5]);
   void   f(double      a[restrict static 3][5]);

все совместимы , то есть вы можете смешивать исопоставляйте их в назначениях указателей на функции без приведения, даже если у вас есть измерение static!

Кажется, что clang (возможно, это правильно) теряет способность что-либо диагностировать, если вызов осуществляется через указатель функции:

void (*f)(double a[restrict static 3]);

int main(void) {
    double a[1] = {0};
    f(a);
}

(в Clang 7.0 нет диагностики - удалите * и вы их получите).

0 голосов
/ 28 декабря 2018

Похоже, это ошибка в GCC.Кажется, были некоторые разногласия относительно того, следует ли об этом сообщать во время компиляции.Тем не менее, это было принято как ошибка, но, кажется, нет приоритета для ее исправления.

Это подробно описано в отчете об ошибке 50584 .Комментарий 9, в частности, гласит:

(В ответ Малкольму Инглису из комментария № 4)

Может ли кто-нибудь изменить статус этой ошибки?

Несмотря на то, хороша ли эта функция или нет, GCC принимает этот код и, по возможности, предупреждает о неопределенном поведении.Таким образом, подтвердил.

Это не значит, что кто-то будет работать над исправлением этого.Пожалуйста, если вы используете эту функцию и хотели бы видеть это предупреждение в GCC, рассмотрите возможность его добавления: https://gcc.gnu.org/wiki/GettingStarted#Basics:_Contributing_to_GCC_in_10_easy_steps

Если вы начнете работать над этим, было бы хорошо сказать об этом здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...