Помогите gcc не предупреждать о неиспользовании строкового литерала - PullRequest
1 голос
/ 27 августа 2009

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

Итак, у меня есть хороший массив со всеми подробными описаниями, проиндексированными, ну и индекс.

Чтобы выгрузить его в буфер, я использую такой код

#define BUFFER_SIZE 40
void format_verbose(uint32_t my_index,
                    char     my_buffer[BUFFER_SIZE])
  {
    snprintf(mY_buffer, BUFFER_SIZE, "%s", MY_ARRAY[my_index].description);
  }

Проблема возникает в некоторых случаях, когда мне нужно вставить другие строки в строку при ее форматировании. Так что я хочу что-то вроде этого (где описание в этом случае содержит %s).

void format_verbose_with_data(uint32_t my_index,
                              char     my_buffer[BUFFER_SIZE])
  {
    // ...
    snprintf(mY_buffer, BUFFER_SIZE, MY_ARRAY[my_index].description,
             some_string);
  }

Наш make-файл настроен на использование (опасного) предупреждения snprintf (), а предупреждения рассматриваются как ошибки. Так что это не скомпилируется. Я хотел бы отключить предупреждение только для этой строки, где, хотя это несколько опасно, я буду контролировать строку и могу проверить, работает ли она с каждым значением, с которым она вызывается.

В качестве альтернативы я был бы рад сделать это другим способом, но я действительно не заинтересован в использовании этого решения

void format_verbose_with_data(uint32_t my_index,
                              char     my_buffer[BUFFER_SIZE])
  {
    // ...
    snprintf(mY_buffer, BUFFER_SIZE, "%s%s%s"
    MY_ARRAY[my_index].description1, some_string,
    MY_ARRAY[my_index].description2);
  }

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

Ответы [ 3 ]

4 голосов
/ 27 августа 2009

GCC не имеет возможности отключать предупреждения построчно, поэтому я подозреваю, что вам не повезло. И в любом случае, если ваши стандарты кодирования говорят, что вы не должны что-то делать, вам не следует искать способы победить их.

Еще один момент, когда вы говорите:

void format_verbose(uint32_t my_index,
                    char     my_buffer[BUFFER_SIZE])

Вы действительно тратите свое время на печатание - яснее и глупее сказать:

void format_verbose(uint32_t my_index,
                    char     my_buffer[])

или

void format_verbose(uint32_t my_index,
                    char     * my_buffer)
0 голосов
/ 15 августа 2014

Если все, что вы когда-либо делаете с snprintf(), копирует строки (как, кажется, имеет место), т.е. все, что у вас когда-либо есть, это один или несколько "%s" в качестве строки формата, почему вы не используя strcpy(), возможно, сначала strlen() для проверки длины источника?

Обратите внимание, что strncpy(), хотя выглядит как хорошая идея, не так. Он всегда заполняет целевой буфер нулями, и в случае, если источник превышает размер буфера, не завершает нулевую строку .

0 голосов
/ 28 августа 2009

После недолгого размышления я планирую вручную разделить входную строку, самостоятельно найдя маркер% s, а затем отправив separetley строк в snprintf () со своими собственными% s. В этом случае, где разрешен только 1 тип строки форматирования, это менее обременительно, однако было бы неестественно попытаться полностью повторно реализовать синтаксический анализатор стиля printf ().

void format_verbose_with_data(uint32_t my_index,
                              char     my_buffer[BUFFER_SIZE])
  {
    char    pre_description[BUFFER_SIZE];
    char    post_description[BUFFER_SIZE];
    int32_t offset = -1;

    offset = find_string(MY_ARRAY[my_index].description, "%s");
    ASSERT(offset >=0, "No split location!");
    // Use offset to copy the pre and post descriptions
    // Exercise left to the reader :-)
    snprintf(mY_buffer, BUFFER_SIZE, "%s%s%s"
             pre_description, some_string, post_description);
  }
...