I find myself often entering in the wrong formatting type, and not remembering when to do f or Lf or lf, etc. Is there a way to do something like the following with the help of the _Generic keyword?
#define TYPE(X) _Generic((X), float: "float", double: "double", long double: "long_double")
#define FORMAT(X) _Generic((X), float: "%f", double: "%f", long double: "%Lf")
printf("%s if of type %s\n", FORMAT(10.), 10., TYPE(10.));
Basically, I want it to print:
10.000000 is of type double
Is there a way to do that?
I suppose one shorthand option would be doing something like:
#define TYPE(X) _Generic((X), float: "float", double: "double", long double: "long_double")
#define STRINGIZE(X) #X
printf("%s if of type %s\n", STRINGIZE(10.), TYPE(10.));
- if of type double
Format specifiers in printf can't be made parameters by themselves. They need to be part of the format string.
You can do this by making the FORMAT macro the entire format string for one call to printf just to print the value. Then you can have another call for the rest:
printf(FORMAT(10.), 10.);
printf(" is of type %s\n", TYPE(10.));
But, as was stated in the comments, modern compilers are smart enough to detect mismatches between printf format strings and their arguments. So relying on that works just as well.
wrong formatting type, and not remembering when to do f or Lf or lf, etc.
Note that for float and double, l or not l are valid as float augments to a ... parameter are promoted to double. The l is optional with printf specifier "%f", and friends: fFeEgGaA.
printf("%f\n", 1.2f);
printf("%f\n", 3.4);
printf("%lf\n", 5.6f); // unusual, yet OK
printf("%lf\n", 7.8);
To use _Generic for printing, perhaps Formatted print without the need to specify type matching specifiers using _Generic.
A useful reason to use different print specifiers for float/double is precision.
#define ForD(X) _Generic((X), float: FLT_DECIMAL_DIG-1, double: DBL_DECIMAL_DIG-1)
printf("%.*e\n", ForD(f), f); // Best if `f` is not be an expression.
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