Существует ли спецификатор printf, который требует float, а не double?


Я получаю ошибки типа MISRA, когда использую спецификатор "%f " для snprintf с параметром типа float.

Согласно моим исследованиям, Мисра прав, потому что" %f " предполагает Тип double.

Существует ли спецификатор или модификатор с плавающей запятой, который будет использовать параметр типа float, а не double?

Я работаю над встроенной системой и не хочу преобразовывать 32-битный float в 64-битный double только для того, чтобы угодить функции snprintf. Код печатается на порт отладки / консоли и это единственное место, где происходит преобразование.

Для тех из вас, кому нужен пример кода:

// This section is for those C++ purists and it fulfills the C++ tag.
#if __cplusplus
#include <cstdio>
#else
#include <stdio.h>
#endif

#define BUFFER_SIZE (128U)

int main(void)
{
    char buffer[BUFFER_SIZE];
    float my_float = 1.234F;

    // The compiler will promote the single precision "my_float"
    //   to double precision before passing to snprintf.
    (void)snprintf(buffer, BUFFER_SIZE, "%10.4f", my_float);
    puts(buffer);
    return 0;
}

Все мои исследования SO и Web посвящены печати значения с плавающей запятой, а не тому, какие спецификаторы потребуют параметра float, чтобы не происходило никакого продвижения к double.

Я использую компилятор IAR Embedded Workbench для процессора ARM7TDMI.

4 6

4 ответа:

Нет, так как printf и его друзья являются вариационными функциями, поэтому параметр float подвергается автоматическому преобразованию в double как часть аргумента по умолчанию (см. раздел 6.5.2.2 стандарта C99).

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

Нет, потому что стандартные акции преобразуют каждый аргумент float в double при передаче через список переменных параметров.

Правильный анализ соответствия MISRA-C:2004 должен дать:

  • Нарушение 1.1, код не соответствует стандарту ISO 9899: 1990 (C++ code, C99 code).
  • Нарушение 2.2, использование / / комментария.
  • Нарушение 16.1, использование функций переменных аргументов.
  • Нарушение 20.9, использование stdio.h.

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

Я проанализировал вручную, а также с помощью тестового стенда LDRA 7.6.0.

Невозможно указать float вместо double в функциях printf из-за автоматического продвижения, но я думаю, что вы можете изменить свой код с:

(void)snprintf(buffer, BUFFER_SIZE, "%10.4f", my_float);

Кому:

(void)snprintf(buffer, BUFFER_SIZE, "%10.4f", (double)my_float);

И добиться нужного результата