Date: Wed, 14 Dec 2016 11:13:48 -0500 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Re: Handling of L and ll prefixes different from glibc On Wed, Dec 14, 2016 at 03:46:40PM +0200, Nadav Har'El wrote: > Hi, > > Posix's printf manual suggests (see > http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html) > that the "ll" format prefix should only be used for integer types, and "L" > should only be used for long double type. And it seems that indeed, this is > what Musl's printf() supports - the test program > > long double d = 123.456; > printf("Lf: %Lf\n", d); > printf("llf %llf\n", d); > long long int i = 123456; > printf("Ld: %Ld\n", i); > printf("lld: %lld\n", i); > > produces with Musl's printf just two lines of output: > > Lf: 123.456000 > lld: 123456 > > The two other printf()s (with %Ld and %llf) are silently dropped. Not quite silently; printf is returning -1 with errno set to EINVAL. > However, in glibc, it seems that "ll" and "L" are synonyms, and both work > for both integer and floating types. The above program produces with glibc > four lines of output: > > Lf: 123.456000 > llf 123.456000 > Ld: 123456 > lld: 123456 > > If Musl's intention is to be compatible with glibc, not Posix, I guess this > behavior should be fixed, and LL and ll should become synonyms, not > different flags? There is no general "intention to be compatible with glibc". There are a couple related topics you might be thinking of: Widely-used and widely-available extensions: There are written-up guidelines for the criteria for inclusion or exclusion of such interfaces, balancing things like usefulness, cost, and whether there's already a better way to do the same thing portably. ABI compatibility: There is an intent to support use of some glibc-linked code in binary form with musl. From a practical standpoint, this is mainly for libraries without source that some users depend on (like flash and eventually nvidia stuff, maybe). Aside from practical needs like that, the scope of the compatibility goal is purely to support fully POSIX-conforming programs, or programs which use common extension APIs provided by musl, not programs relying on unsupported glibc functionality, doing things gratuitously wrong (like ll vs L here), or depending on glibc bugs. Now back to the topic of printf: As for printf formats specifically, musl avoids defining any of the cases which are undefined behavior in order to avoid getting in a situation where we conflict with future versions of the standard. This happened with glibc's scanf, which took 'a' as an extension flag for auto-allocation, only to have C99 later assign it for floating point (to match printf hex formatting), and glibc had to use hackery of remapping symbols in different conformance profiles to work around the problem. musl does not do that kind of hackery, so we have to be careful not to introduce such problems in the first place. Note that there is one printf extension we have, %m, but this is because POSIX requires %m to be supported by syslog(), making it unlikely that the standards would assign a conflicting meaning in the future. Also %m is very useful, whereas mismatched L/ll is just programmer sloppiness. One thing I'm not happy with now is the way printf returns an error (which the caller usually ignores) on invalid format strings; this hides lots of bugs (for example, a similar issue with some legacy software using %qd for printing long long) and doesn't have any basis in requirements, since invalid format strings invoke undefined behavior. I'm mildly leaning towards causing a crash on invalid format strings so that the location of the incorrect usage can be quickly found with a debugger, but I'd like feedback from users who've debugged this sort of thing on whether that'd actually be helpful. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.