Почему 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'
что я и ожидал увидеть.
Итак, почему предупреждение?
Ответы
Ответ 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"