Почему gcc -Wall дает предупреждение о строках формата нулевой длины? - программирование
Подтвердить что ты не робот

Почему gcc -Wall дает предупреждение о строках формата нулевой длины?

Я немного искал информацию об этом, но не нашел ничего удовлетворительного. Есть ли какое-то особое поведение для вызова функции

sprintf(someString, "");

что объясняет, почему это предупреждение (на gcc с -Wall)? Мне только удалось найти, что стандарт C допускает нулевые строки формата.

Я попробовал следующий пример

#include <stdio.h>

int main()
{
    char str[2] = {'a', 'a'};
    sprintf(str, "");
    printf("\'%c\'\'%c\'\n", str[0], str[1]);
    return 0;
}

который выводит

'''a'

что я и ожидал увидеть. Итак, почему предупреждение?

4b9b3361

Ответ 1

Тот факт, что GCC выдает предупреждение, обычно не имеет никакого отношения к тому, является ли конструкция законной C, но не считают ли разработчики GCC ее либо вероятным признаком того, что вы имели в виду нечто иное, чем то, что вы пишете, или просто плохой стиль. Вот несколько примеров:

  • if (x = 0) - вы почти наверняка имели в виду if (x == 0).
  • printf(str) - вы почти наверняка имели в виду либо fputs(str, stdout), либо printf("%s", str); как написано, код очень опасен.
  • if (foo == bar & MASK) - вы почти наверняка имели в виду if (foo == (bar & MASK)).

и др.

В вашем случае, я думаю, что GCC ставит под сомнение, почему вы вызываете sprintf(String, ""), чтобы сделать эквивалент String[0]=0; (последний намного короче, быстрее и понятнее).

Ответ 2

Вы получаете предупреждение, потому что gcc знает, что второй аргумент sprintf() должен быть непустой строкой, обычно с различными спецификациями формата - функционально эквивалентным и "более законным" вызовом того, который вы в вашем коде будет sprintf(str, "%s", ""). Кроме того, почти всегда от одного до N дополнительных аргументов достаточно, чтобы соответствовать спецификациям формата. Поскольку вы используете его здесь, вы используете его как своего рода strcpy(), который, хотя и технически обоснован, является очень странным способом использования стандартной библиотеки.

Ответ 3

Это просто предупреждение от GCC. Если вы хотите подавить его для одной части вашего приложения, вы можете сделать следующее:

#pragma GCC diagnostic ignored "-Wformat-zero-length"
int main()
{
     // code that produces a warning
}
#pragma GCC diagnostic warning "-Wformat-zero-length"