Path: csiph.com!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: printf format specifier changes Date: Fri, 11 Sep 2015 16:23:03 -0700 Organization: None to speak of Lines: 90 Message-ID: References: <1fe6466f-8b9c-40e6-8ce3-a5209c08fa7a@googlegroups.com> <7d3eddec-100b-4362-a987-c365c5a414cf@googlegroups.com> <1b85e519-b814-4570-b61b-705aca90a1b4@googlegroups.com> <893e3f42-e89d-4c9b-bdfe-cb9e577c3c3b@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx02.eternal-september.org; posting-host="945944de09706c9b4e29b53c9d2efdc2"; logging-data="11448"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19c279Q+bgH0/B+7jH3kqZy" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:EQN/gDHfjguDpVa6Z05suUoqhZ8= sha1:F+2hHYHgMQovaU8bIbPpA37aYsA= Xref: csiph.com comp.lang.c:70287 supercat@casperkitty.com writes: > On Thursday, September 10, 2015 at 7:31:45 PM UTC-5, Keith Thompson wrote: [...] >> C doesn't provide a way to determine the relative efficiencies of the >> floating-point types. It might be nice to have something like the >> int_fastN_t types, but for floating-point. > > The easy semantics, were it not for printf issues, would be to have a type > defined as "the type to which floats promote" [much as "ptrdiff_t" is "the > type yielded when subtracting pointers], a type defined as "the type to > which double values promote", and an optional type which, on systems that > support it, would represent an extended-precision floating-point number. They're called float_t and double_t, defined in . I believe they were introduced by C99. > I would suggest that the most natural meaning for "long double" would have > been "the type to which double values promote", given that the most widely > used platforms that supported the 80-bit type, performed math on doubles by > promoting to that type. I dislike that idea. float, double, and long double are three distinct floating-point types (of which two or more might happen to have the same representation). C doesn't tie the definition of any of those types to operations on another type, and IMHO it shouldn't. C also lets an implementation specify how floating-point operations are evaluated; see FLT_EVAL_METHOD in N1570 5.2.4.2.2. >> If the implementation has an 80-bit long double type, then a library >> that doesn't support it is non-conforming. > > If a system is going to promote double values to 80 bits when performing > arithmetic on them, but it's necessary that generated code be compatible > with libraries that were written before the invention of "long double", [snip] "long double" was introduced to the language by the 1989 ANSI C standard. Neither it nor the two later standards make specific allowances for compatibility with non-conforming implementations that don't support long double. A more realistic scenario is having a compiler that assumes one representation for long double and a runtime library that assumes a different representation (this is a problem for MinGW). That's just a matter of building an implementation that behaves consistently. >> I have no idea why Microsoft decided to make double and long double the >> same size (which is perfectly valid as far as the C standard is >> concerned). Are you suggesting that they did it to avoid confusion with >> printf format strings? (Incidentally, printing a long double value with >> "%f" or "%lf" is incorrect even if long double happens to have the same >> representation as double, though it's likely to "work".) > > Of course using anything other than "%lF" for "long double" is Undefined > Behavior, I presume that was a typo for "%Lf". Of course you can also use "%Le" or "%Lg", but yes. > but programmers want stuff to work. Then they should use the correct format string. [...] >> There are already ways to deal with passing arbitrary integer types to >> printf. The simplest is to cast to [u]intmax_t and use "%jd" or "%ju". >> Or you can use the macros defined in . I don't think it's >> necessary to mess with the way arguments to variadic functions are >> promoted. > > If one has a mountain of existing code which prints 32-bit values using "%ld" > and wishes to port it to a system where `long` is 64 bits, having an option > to make all "printf"-related functions map to library routines that expect > all integer types to be passed as 64-bits would be a lot more convenient > than having to identify everyplace that uses a "%ld" to print 32-bit values > and change them to "%d" while making certain not to accidentally change any > places that are trying to print 64-bit values. If one has a mountain of incorrect code, some hack to make it "work" by making printf behave incorrectly might be convenient. I'd rather fix the code. (I'd rather write it correctly in the first place, but of course that's not always an option.) -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"