Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is clang 3.8 warning on use of float with %f printf format specifier? [duplicate]

This code:

#include <stdio.h>
int main(void)
{
  float value = 10.10f;
  printf("%f\n",value);
}

compiled with the -Weverything option using clang 3.8 on Ubuntu 14.04.1 gives:

clang -Weverything w-double-precision.c 
w-double-precision.c:5:17: warning: implicit conversion increases floating-point precision: 'float' to 'double' [-Wdouble-promotion]
  printf("%f\n",value);
  ~~~~~~        ^~~~~
1 warning generated. 
like image 933
Scooter Avatar asked Mar 25 '17 02:03

Scooter


People also ask

Why %F can be used for both float and double in printf?

We can print the double value using both %f and %lf format specifier because printf treats both float and double are same. So, we can use both %f and %lf to print a double value.

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.

Is %d for double in C?

%d stands for decimal and it expects an argument of type int (or some smaller signed integer type that then gets promoted). Floating-point types float and double both get passed the same way (promoted to double ) and both of them use %f .

What format does Clang use for _float16?

As with __fp16, Clang uses the binary16 format from IEEE 754-2008 for _Float16. _Float16 arithmetic will be performed using native half-precision support when available on the target (e.g. on ARMv8.2a); otherwise it will be performed at a higher precision (currently always float) and then truncated down to _Float16.

What are the floating point types supported by Clang?

Clang supports three half-precision (16-bit) floating point types: __fp16 , _Float16 and __bf16. These types are supported in all language modes. __fp16 is supported on every target, as it is purely a storage format; see below. _Float16 is currently only supported on the following targets, with further targets pending ABI standardization:

How to limit code growth through included files in Clang?

This diagnostic is enabled by default. As a per-translation unit limit using the clang max_tokens_total pragma, which works like and overrides the -fmax-tokens= flag: These limits can be helpful in limiting code growth through included files.

What is a *%P specifier in Clang?

A *%p specifier will be used for a field that Clang doesn’t know how to format, and the corresopnding argument will be a pointer to the field. This allows a C++ templated formatting function to detect this case and implement custom formatting. A * will otherwise not precede a format specifier. This builtin does not return a value.


1 Answers

The printf() function is a variadic, or vararg, function; one that accepts a variable number of arguments. The way the printf() function is defined in cppreference.com is as follows:

int printf( const char *format, ... );

The ... indicates that this function can accept a variable number of arguments.

In a variadic function, if a variable of type float is passed to it, it will automatically convert it to a double value; an implicit conversion from type float to type double is done.

In your code, you pass a floating point-type variable value to printf(), as an additional argument in addition to the "%f\n" parameter. Hence, since printf() is a vararg function, it convert value to type double before passing it as an argument. Depending on how high you have kept your compiler's warnings, it is giving you that warning.

Hope this helps!

like image 171
BusyProgrammer Avatar answered Oct 28 '22 22:10

BusyProgrammer