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.
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.
"%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.
%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 .
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.
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:
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.
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With