问题
I'm getting MISRA type errors when I use "%f" specifier for snprintf
with a parameter of type float
.
According to my research, MISRA is correct because "%f" expectes a type of double
.
Is there a floating point specifier or modifier that will use a float
type parameter and not a double
?
I'm working on an embedded system and don't want to convert from 32-bit float to 64-bit double
just to please the snprintf
function. The code prints to the debug / console port and this is the only place where the conversion takes place.
For those of you needing a code example:
// 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;
}
All my research on SO and the Web is about printing a floating point value, not about which specifiers will require a float
parameter so that no promotion to double
takes place.
I am using IAR Embedded Workbench compiler for ARM7TDMI processor.
回答1:
No, because printf
and its friends are variadic functions, so a float
parameter undergoes automatic conversion to double
as part of the default argument promotions (see section 6.5.2.2 of the C99 standard).
I'm not sure why this triggers a MISRA warning though, I can't think of any way in which this might be dangerous.
回答2:
No, there's not, because the standard promotions convert every float
argument into a double
when passed through a variable parameter list.
回答3:
Correct MISRA-C:2004 compliance analysis should give:
- Violation of 1.1, code does not conform to ISO 9899:1990 (C++ code, C99 code).
- Violation of 2.2, use of // comment.
- Violation of 16.1, use of variable argument functions.
- Violation of 20.9, use of stdio.h.
If you get other errors than those above, your static analyser might be broken.
I have analysed manually, as well as with LDRA Testbed 7.6.0.
回答4:
it's not possible specify float instead of double in printf functions because of automatic promotion, but I think you can change your code from:
(void)snprintf(buffer, BUFFER_SIZE, "%10.4f", my_float);
to:
(void)snprintf(buffer, BUFFER_SIZE, "%10.4f", (double)my_float);
and achieve the right result
来源:https://stackoverflow.com/questions/14227028/is-there-a-printf-specifier-that-requires-float-not-double