Reputation: 1478
the c99 standard (ISO/IEC 9899:1999) says that the length field of pintf format placeholder can be L, that apply only to float number. Thi is confirmed also in printf(3) manpage:
L
A following a, A, e, E, f, F, g, or G conversion corresponds to a long double argument.
If I compile this:
printf("%Ld",3);
using -std=c99 gcc argument, I get a warning:
warning: format ‘%Ld’ expects argument of type ‘long long int’, but argument 2 has type ‘int’ [-Wformat=]
printf("%Ld",3);
^
It seems that gnu libc does not folloe c99 standard
I have gcc 6.3.0, gnu libc 2.24, my host is a linux ubuntu 17.04 64bit
[Edited]
if I compile this:
printf("%Ld\n",3);
printf("%lld\n", 3LL);
printf("%Lf\n", 3.3L);
printf("%llf\n", 3.3L);
printf("%f\n", 3.3L);
I get:
warning: format ‘%Ld’ expects argument of type ‘long long int’, but argument 2 has type ‘int’ [-Wformat=]
printf("%Ld\n",3);
^
warning: use of ‘ll’ length modifier with ‘f’ type character has either no effect or undefined behavior [-Wformat=]
printf("%llf\n", 3.3L);
^
warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘long double’ [-Wformat=]
printf("%f\n", 3.3L);
^
So the expected warning message is like for %llf
.
with -pedantic I get more verbose messages:
warning: ISO C does not support the ‘%Ld’ gnu_printf format [-Wformat=]
printf("%Ld\n",3);
^
warning: format ‘%Ld’ expects argument of type ‘long long int’, but argument 2 has type ‘int’ [-Wformat=]
warning: use of ‘ll’ length modifier with ‘f’ type character has either no effect or undefined behavior [-Wformat=]
printf("%llf\n", 3.3L);
^
warning: format ‘%f’ expects argument of type ‘double’, but argument 2 has type ‘long double’ [-Wformat=]
printf("%f\n", 3.3L);
^
[Edited]
I have a mail from gcc ML
it looks that '%Ld' is allowed and require ‘long long int’.
But it is allowed by GNU libc, that's the point. For GNU libc %Ld means the same as %lld, but that's non-standard, so when you use -pedantic you get a warning.
And this explain the warning message.
Upvotes: 1
Views: 702
Reputation: 41474
The standard says:
If a length modifier appears with any conversion specifier other than as specified above, the behavior is undefined.
In this case, the L
length modifier is not specified for use with the d
conversion specifier, so the behavior is undefined.
Presumably gcc (this is gcc giving you the warning, not libc) is using the same internal flag for long doubles and long long ints. It would be nice if the warning were more precise, but it isn't required to give you any warning at all (or to do anything else in particular), so it's following the standard correctly.
Upvotes: 1