Почему gcc -Wall выдает предупреждение о строке формата нулевой длины? - PullRequest
20 голосов
/ 29 марта 2012

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

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'

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

Ответы [ 3 ]

23 голосов
/ 29 марта 2012

Тот факт, что 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; (последний намного короче, быстрее и четче).

5 голосов
/ 29 марта 2012

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

4 голосов
/ 29 марта 2012

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

...