Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a printf specifier that requires float not double?

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.

like image 281
Thomas Matthews Avatar asked Jan 09 '13 01:01

Thomas Matthews


People also ask

Is %f for float or double?

The following piece of code will demonstrate this point. %f is the format string for a float, the single precision floating-point type. %lf is the format string for a double, the double precision floating-point type.

Is %F for double?

"%f" is the (or at least one) correct format for a double. There is no format for a float , because if you attempt to pass a float to printf , it'll be promoted to double before printf receives it1.

Can we use %d for float?

no %d is decimal integer. use %f or %lf. you cannot send a float to printf().

Is a format specifier for float in printf ()?

printf("%9.6f", myFloat) specifies a format with 9 total characters: 2 digits before the dot, the dot itself, and six digits after the dot.


3 Answers

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.

like image 163
Oliver Charlesworth Avatar answered Sep 20 '22 12:09

Oliver Charlesworth


No, there's not, because the standard promotions convert every float argument into a double when passed through a variable parameter list.

like image 36
Kerrek SB Avatar answered Sep 16 '22 12:09

Kerrek SB


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.

like image 40
Lundin Avatar answered Sep 18 '22 12:09

Lundin