Я получаю ошибки типа MISRA при использовании спецификатора «% f» для snprintf
с параметром типа float
,
Согласно моему исследованию, MISRA верна, потому что «% f» предполагает тип double
,
Есть ли спецификатор или модификатор с плавающей запятой, который будет использовать float
параметр типа, а не double
?
Я работаю над встроенной системой и не хочу конвертировать из 32-битного с плавающей точкой в 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.
Нет потому что printf
и его друзья — это различные функции, так что float
параметр подвергается автоматическому преобразованию в double
как часть продвижение аргумента по умолчанию (см. раздел 6.5.2.2 стандарта C99).
Я не уверен, почему это вызывает предупреждение MISRA, хотя я не могу придумать, каким образом это может быть опасно.
Нет, потому что стандартные рекламные акции конвертируют каждый float
аргумент в double
когда передается через список переменных параметров.
Правильный анализ соответствия MISRA-C: 2004 должен дать:
Если вы получите другие ошибки, кроме указанных выше, ваш статический анализатор может быть неисправен.
Я проанализировал вручную, а также с LDRA Testbed 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);
и достичь правильного результата