Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #64771 > unrolled thread

printf format specifier changes

Started by"Rick C. Hodgin" <rick.c.hodgin@gmail.com>
First post2015-07-06 09:04 -0700
Last post2015-07-09 15:25 -0700
Articles 20 on this page of 146 — 28 participants

Back to article view | Back to comp.lang.c


Contents

  printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-06 09:04 -0700
    Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-06 17:50 +0100
      Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-06 11:34 -0700
        Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-06 19:47 +0100
          Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-06 19:53 +0100
            Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-06 11:57 -0700
        Re: printf format specifier changes "James Harris" <james.harris.1@gmail.com> - 2015-09-06 10:53 +0100
          Re: printf format specifier changes Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-06 04:21 -0700
            Re: printf format specifier changes "James Harris" <james.harris.1@gmail.com> - 2015-09-07 10:40 +0100
              Re: printf format specifier changes Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-07 03:07 -0700
                Re: printf format specifier changes "James Harris" <james.harris.1@gmail.com> - 2015-09-07 15:09 +0100
              Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-07 12:03 +0100
                Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-07 12:46 +0100
                  Re: printf format specifier changes "James Harris" <james.harris.1@gmail.com> - 2015-09-07 15:24 +0100
                Re: printf format specifier changes "James Harris" <james.harris.1@gmail.com> - 2015-09-07 15:16 +0100
                  Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-07 17:09 +0100
                    Re: printf format specifier changes "James Harris" <james.harris.1@gmail.com> - 2015-09-07 17:47 +0100
                    Re: printf format specifier changes Richard Damon <Richard@Damon-Family.org> - 2015-09-07 13:29 -0400
                      Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-08 12:17 +0100
                        Re: printf format specifier changes Robert Wessel <robertwessel2@yahoo.com> - 2015-09-08 10:13 -0500
                          Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-08 17:09 +0100
                            Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-08 10:08 -0700
                              Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-08 19:11 +0100
                                Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-08 12:24 -0700
                                  Re: printf format specifier changes Robert Wessel <robertwessel2@yahoo.com> - 2015-09-08 14:56 -0500
                                  Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-08 22:18 +0100
                                    Re: printf format specifier changes Ian Collins <ian-news@hotmail.com> - 2015-09-09 09:29 +1200
                                      Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-08 22:58 +0100
                                        Re: printf format specifier changes Ian Collins <ian-news@hotmail.com> - 2015-09-09 10:32 +1200
                                          Re: printf format specifier changes supercat@casperkitty.com - 2015-09-08 15:57 -0700
                                    Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-08 15:12 -0700
                                      Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-08 23:45 +0100
                                        Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-08 16:36 -0700
                                        Re: printf format specifier changes Robert Wessel <robertwessel2@yahoo.com> - 2015-09-08 19:17 -0500
                                          Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-09 09:56 +0100
                                            Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-09 11:33 -0700
                                              Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-09-09 20:35 +0100
                                Re: printf format specifier changes Robert Wessel <robertwessel2@yahoo.com> - 2015-09-08 14:51 -0500
                              Re: printf format specifier changes David Brown <david.brown@hesbynett.no> - 2015-09-08 22:41 +0200
                Re: printf format specifier changes Richard Damon <Richard@Damon-Family.org> - 2015-09-07 12:03 -0400
            Re: printf format specifier changes glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-09-10 06:33 +0000
              Re: printf format specifier changes Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-10 02:38 -0700
            Re: printf format specifier changes supercat@casperkitty.com - 2015-09-10 07:01 -0700
              Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-10 12:47 -0700
                Re: printf format specifier changes supercat@casperkitty.com - 2015-09-10 14:08 -0700
                  Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-10 15:17 -0700
                    Re: printf format specifier changes supercat@casperkitty.com - 2015-09-10 16:02 -0700
                      Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-10 17:31 -0700
                        Re: printf format specifier changes supercat@casperkitty.com - 2015-09-11 15:43 -0700
                          Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-09-11 16:23 -0700
                        Re: printf format specifier changes Robert Wessel <robertwessel2@yahoo.com> - 2015-09-11 23:33 -0500
                      Re: printf format specifier changes Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-11 21:44 -0700
                        Re: printf format specifier changes supercat@casperkitty.com - 2015-09-12 09:02 -0700
                          Re: printf format specifier changes Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-26 15:00 -0700
                            Re: printf format specifier changes supercat@casperkitty.com - 2015-09-27 11:21 -0700
                              Re: printf format specifier changes Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-29 10:10 -0700
          Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-06 13:41 +0100
            Re: printf format specifier changes Robert Wessel <robertwessel2@yahoo.com> - 2015-09-07 00:23 -0500
            Re: printf format specifier changes "James Harris" <james.harris.1@gmail.com> - 2015-09-07 11:31 +0100
              Re: printf format specifier changes Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-07 03:54 -0700
      Re: printf format specifier changes Richard Heathfield <rjh@cpax.org.uk> - 2015-07-06 19:44 +0100
        Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-06 22:14 +0100
          Re: printf format specifier changes Robert Wessel <robertwessel2@yahoo.com> - 2015-07-06 22:43 -0500
          Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-06 23:01 -0700
            Re: printf format specifier changes glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-07-07 06:43 +0000
            Re: printf format specifier changes Phil Carmody <pc+usenet@asdf.org> - 2015-07-09 10:52 +0300
              Re: printf format specifier changes Richard Heathfield <rjh@cpax.org.uk> - 2015-07-09 09:26 +0100
                Re: printf format specifier changes Phil Carmody <pc+usenet@asdf.org> - 2015-07-12 12:56 +0300
                  Re: printf format specifier changes Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-07-12 06:12 -0700
          Re: printf format specifier changes Rosario19 <Ros@invalid.invalid> - 2015-07-07 10:22 +0200
            Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-07 10:10 +0100
        Re: printf format specifier changes Philip Lantz <prl@canterey.us> - 2015-07-07 00:54 -0700
      Re: printf format specifier changes Nobody <nobody@nowhere.invalid> - 2015-07-07 15:08 +0100
        Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-07 16:12 +0100
          Re: printf format specifier changes raltbos@xs4all.nl (Richard Bos) - 2015-07-09 10:34 +0000
            Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-09 12:25 +0100
              Re: printf format specifier changes Phil Carmody <pc+usenet@asdf.org> - 2015-07-12 13:02 +0300
                Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-12 11:23 +0100
      Re: printf format specifier changes <william@wilbur.25thandClement.com> - 2015-07-07 11:50 -0700
        Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-07 12:14 -0700
      Re: printf format specifier changes Les Cargill <lcargill99@comcast.com> - 2015-07-07 21:52 -0500
        Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-07 20:42 -0700
          Re: printf format specifier changes Phil Carmody <pc+usenet@asdf.org> - 2015-07-09 11:12 +0300
            Re: printf format specifier changes Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-07-09 05:03 -0700
              Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-09 13:10 -0500
            Re: printf format specifier changes James Kuyper <jameskuyper@verizon.net> - 2015-07-09 08:58 -0400
            Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-09 08:10 -0700
              Re: printf format specifier changes Phil Carmody <pc+usenet@asdf.org> - 2015-07-12 12:58 +0300
                Re: printf format specifier changes James Kuyper <jameskuyper@verizon.net> - 2015-07-12 12:57 -0400
                Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-12 11:14 -0700
                  Re: printf format specifier changes gazelle@shell.xmission.com (Kenny McCormack) - 2015-07-12 18:26 +0000
        Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-08 13:09 +0100
        Re: printf format specifier changes James Kuyper <jameskuyper@verizon.net> - 2015-07-08 08:10 -0400
          Re: printf format specifier changes Les Cargill <lcargill99@comcast.com> - 2015-07-08 08:12 -0500
            Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-08 08:38 -0700
            Re: printf format specifier changes James Kuyper <jameskuyper@verizon.net> - 2015-07-08 12:00 -0400
              Re: printf format specifier changes Les Cargill <lcargill99@comcast.com> - 2015-07-08 17:20 -0500
        Re: printf format specifier changes Phil Carmody <pc+usenet@asdf.org> - 2015-07-09 11:08 +0300
      Re: printf format specifier changes Phil Carmody <pc+usenet@asdf.org> - 2015-07-08 20:30 +0300
        Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-08 18:56 +0100
          Re: printf format specifier changes gordonb.lmwiv@burditt.org (Gordon Burditt) - 2015-07-09 11:09 -0500
            Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-09 14:05 -0500
        Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-08 11:27 -0700
          Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-08 15:07 -0500
    Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-06 23:39 -0500
      Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-07 10:19 +0100
        Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-07 07:57 -0500
          Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-07 14:15 +0100
            Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-07 14:46 +0100
            Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-07 09:37 -0500
          Re: printf format specifier changes Phil Carmody <pc+usenet@asdf.org> - 2015-07-09 11:24 +0300
            Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-09 09:55 -0500
              Re: printf format specifier changes <william@wilbur.25thandClement.com> - 2015-07-09 11:53 -0700
                Re: printf format specifier changes <william@wilbur.25thandClement.com> - 2015-07-09 13:48 -0700
                Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-09 17:01 -0500
      Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-07 10:59 +0100
        Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-07 07:48 -0500
          Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-07 14:30 +0100
            Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-07 10:05 -0500
              Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-07 23:16 +0100
                Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-07 20:29 -0500
                Re: printf format specifier changes Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-07-08 00:43 -0700
                Re: printf format specifier changes Robert Wessel <robertwessel2@yahoo.com> - 2015-07-09 02:29 -0500
                  Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-09 10:34 +0100
                    Re: printf format specifier changes BGB <cr88192@hotmail.com> - 2015-07-09 09:35 -0500
            Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-07 08:37 -0700
              Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-07 08:45 -0700
              Re: printf format specifier changes supercat@casperkitty.com - 2015-09-07 08:29 -0700
            Re: printf format specifier changes <william@wilbur.25thandClement.com> - 2015-07-07 12:12 -0700
    Re: printf format specifier changes pooja deshpande <namitadeshpande25@gmail.com> - 2015-07-09 09:29 -0700
      Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-09 09:34 -0700
        Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-09 09:59 -0700
          Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-09 22:33 +0100
            Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-09 15:17 -0700
              Re: printf format specifier changes glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-07-10 00:30 +0000
                Re: printf format specifier changes Reinhardt Behm <rbehm@hushmail.com> - 2015-07-10 09:17 +0800
        Re: printf format specifier changes David Kleinecke <dkleinecke@gmail.com> - 2015-07-09 10:02 -0700
          Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-09 10:19 -0700
        Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-09 21:50 +0100
          Re: printf format specifier changes Keith Thompson <kst-u@mib.org> - 2015-07-09 15:05 -0700
            Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-09 15:09 -0700
            Re: printf format specifier changes Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-07-10 00:28 +0100
              Re: printf format specifier changes raltbos@xs4all.nl (Richard Bos) - 2015-07-13 20:39 +0000
          Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-09 15:07 -0700
            Re: printf format specifier changes Bartc <bc@freeuk.com> - 2015-07-09 23:16 +0100
              Re: printf format specifier changes "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-07-09 15:25 -0700

Page 3 of 8 — ← Prev page 1 2 [3] 4 5 6 7 8  Next page →


#70125

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2015-09-10 06:33 +0000
Message-ID<msr87r$v2a$1@speranza.aioe.org>
In reply to#69596
Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> On Sunday, September 6, 2015 at 10:53:25 AM UTC+1, James Harris wrote:

(snip)
>> IMO the standard library printf approach is very C'ish in that it is 
>> fast and flexible and a bit dangerous. Another language may have 
>> something which is safer and a little more flexible but slower.
 
> Speed doesn't normally matter much for this type of string handling, 
> unless you're spewing out vast quantities of data for automatic parsing. 

It isn't so unusual to use human readable forms for data transfer,
when normally only computers will read it. I have known some printf()
with especially slow coversions.

> If the output is intended for human reading, or the 
> input represents measurements of some type taken by a human, 
> then on any halfway modern computer the
> time to format the string will be negligible.

For large enough data sets, it isn't negligible. 

> But safety isn't much of an issue either. 
> A bug in a  call to printf() will usually be very quickly 
> found because it's only one step away from the faulty output.
> The exception is where you pass a dynamic format string and someone embeds 
> the wrong conversion types in it, often by falling to escape %.

-- glen

[toc] | [prev] | [next] | [standalone]


#70144

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-09-10 02:38 -0700
Message-ID<9331979b-a3c4-4513-9580-bce19d05d760@googlegroups.com>
In reply to#70125
On Thursday, September 10, 2015 at 7:33:43 AM UTC+1, glen herrmannsfeldt wrote:
> Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
>
> > If the output is intended for human reading, or the 
> > input represents measurements of some type taken by a human, 
> > then on any halfway modern computer the
> > time to format the string will be negligible.
> 
> For large enough data sets, it isn't negligible. 
> 
No human can take enough measurements to generate a dataset that will in
any sense stress of challenge a modern computer, regardless of the amount
of micro-optimisation/pessimisation in the text-reading / writing functions.

Only automatic devices that take huge numbers of samples can do that.

[toc] | [prev] | [next] | [standalone]


#70169

Fromsupercat@casperkitty.com
Date2015-09-10 07:01 -0700
Message-ID<1b85e519-b814-4570-b61b-705aca90a1b4@googlegroups.com>
In reply to#69596
On Sunday, September 6, 2015 at 6:21:49 AM UTC-5, Malcolm McLean wrote:
> But safety isn't much of an issue either. A bug in a  call to printf() will usually
> be very quickly found because it's only one step away from the faulty output.
> The exception is where you pass a dynamic format string and someone embeds 
> the wrong conversion types in it, often by falling to escape %.

Because ANSI failed to specify a means by which a prototype can indicate
whether a variadic function expects floating-point values to be passed as
double or long double, a significant fraction--perhaps a majority--of code
which uses "long double" values and prints them uses the wrong format string,
and only works because the its platform made "long double" and "double"
synonymous, and regards the undefined "%lf" as a synonym for and "%f".

IMHO, ANSI C should have included four mandatory types, and allowed for a
fifth optional intrinsic.

   double      -- Typically 64 bits

   float       -- Typically 32 bits

   long double -- Type of constants, and yielded by operators where at least
                  one operand is double.  Typically 64 or 80 bits.

   long float  -- Type yielded by operations where neither operand is double
                  but at least one is float.  Typical sizes would be 32, 40,
                  48, 64, or 80 bits (on an ARM without an FPU, it may have
                  32 bit mantissa, 16 bit exponent, 16 bit sign--64 bits, but
                  not a double).

   __extended  -- If supported, an IEEE extended-precision type with at least
                  64 bits of mantissa.

C was designed with the intention that all floating-point values passed to a
variadic function should be coerced to the same format; if ANSI C had kept
that tradition, code could be written to achieve optimal semantics (wasting
minimal time on conversions) when used with nearly all compilers for platforms
with and without FPUs.  Unfortunately, the fact that "printf" requires code to
distinguish between "double" and longer floating-point types, and does so in a
way that much if not most code gets wrong, compelled many compiler vendors to
omit from the language the type which is yielded by operations on floating
point values.

[toc] | [prev] | [next] | [standalone]


#70188

FromKeith Thompson <kst-u@mib.org>
Date2015-09-10 12:47 -0700
Message-ID<lnegi6njjj.fsf@kst-u.example.com>
In reply to#70169
supercat@casperkitty.com writes:
> On Sunday, September 6, 2015 at 6:21:49 AM UTC-5, Malcolm McLean wrote:
>> But safety isn't much of an issue either. A bug in a call to printf()
>> will usually be very quickly found because it's only one step away
>> from the faulty output.  The exception is where you pass a dynamic
>> format string and someone embeds the wrong conversion types in it,
>> often by falling to escape %.
>
> Because ANSI failed to specify a means by which a prototype can
> indicate whether a variadic function expects floating-point values to
> be passed as double or long double, a significant fraction--perhaps a
> majority--of code which uses "long double" values and prints them uses
> the wrong format string, and only works because the its platform made
> "long double" and "double" synonymous, and regards the undefined "%lf"
> as a synonym for and "%f".

ANSI (and ISO) specified that float arguments are promoted to double,
and double and long double arguments are passed as they are.  The rules
are unambiguous.

Would you want to make it impossible to pass both double and long double
arguments to the same variadic function?  For example, this is perfectly
legal:

    float f = 1.0;
    double d = 2.0;
    long double ld = 3.0;
    printf("%f %f %Lf\n", f, d, ld);

Certainly some code gets format strings wrong.  I'm skeptical that most
code does so.  (I'm not sure how much code even uses long double; double
is sufficient for most purposes.)

C99 made "%lf" synonymous with "%f".

I think making double and long double the same size is mostly a Windows
thing; gcc gives long double a greater size, range, and precision than
double.

[...]

> C was designed with the intention that all floating-point values
> passed to a variadic function should be coerced to the same format; if
> ANSI C had kept that tradition, code could be written to achieve
> optimal semantics (wasting minimal time on conversions) when used with
> nearly all compilers for platforms with and without FPUs.
> Unfortunately, the fact that "printf" requires code to distinguish
> between "double" and longer floating-point types, and does so in a way
> that much if not most code gets wrong, compelled many compiler vendors
> to omit from the language the type which is yielded by operations on
> floating point values.

Pre-ANSI C only had float and double.  ANSI added long double.
On some implementations, long double might be substantially less
efficient than double, so promoting double arguments to long double
could be inefficient.

Remembering to use "%f" for double and "%Lf" for long double should be
no more difficult than remembering to use "%d", "%ld", and "%lld" for
int, long, and long long.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
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"

[toc] | [prev] | [next] | [standalone]


#70191

Fromsupercat@casperkitty.com
Date2015-09-10 14:08 -0700
Message-ID<f3e9e095-260e-42e8-9fef-c9ea06e18e4f@googlegroups.com>
In reply to#70188
On Thursday, September 10, 2015 at 2:47:44 PM UTC-5, Keith Thompson wrote:
> ANSI (and ISO) specified that float arguments are promoted to double,
> and double and long double arguments are passed as they are.  The rules
> are unambiguous.

Unambiguous does not mean helpful, and the ambiguity is not so much in the
prototype itself, but numeric promotions elsewhere.  On some platforms
(*especially those without floating-point units*), the most efficient way
to perform operations on floating-point values is to convert all values to
an extended-precision type and perform computations with that type, and
then coerce the value as needed when assigning it into a variable or
parameter.  If the language makes the extended precision type available to
the programmer, this approach allows floating-point calculations to be faster,
easier, and more understandable than otherwise possible.

The problem arises with code like:

    double d1 = 123456789.0;
    double d2 = 123456789.1 - d1;

From a semantic standpoint, if the compiler can subtract d1 from
123456789.09999999999999999991, yielding 0.09999999999999999991 just as
cheaply as it can subtract from 123456789.099999994039535522, the former
is far more likely to be the desired behavior.  That creates a problem,
though, of what the type of the numeric literal should be.  If all
floating-point arguments were passed to printf the same way, as had been
the case in C as originally designed, the exact type of the value wouldn't
matter, but the incompatible treatment of "long double" adds many more
complications.

> Would you want to make it impossible to pass both double and long double
> arguments to the same variadic function?  For example, this is perfectly
> legal:
> 
>     float f = 1.0;
>     double d = 2.0;
>     long double ld = 3.0;
>     printf("%f %f %Lf\n", f, d, ld);

Nothing wrong with that, but this should be legal *AS WELL*

     printf("%f %f %f\n", f, d, ld);

If a library's ABI for printf requires that it receive floating-point values
in 64-bit format, the long double should be rounded down to that format; if
the ABI requires 80-bit values, the double should be extended to 80 bits.
If I'd been in charge of the language, a simple `...` would coerce all
floating-point values to the same implementation-defined type, but I would
have also allowed a syntax like:

   int printf(const char*format, ... {int, long, unsigned int,
              unsigned long, double, void*});

to specify that all arguments must be coerced to one of the listed types.  If
the printf implementation expected 80-bit floating-point values and wanted to
maximize compatibility with 16-bit and 32-bit code:

   int printf(const char*format, ... {long, unsigned long, long double,
              void*});

in which case it could then regard "%ld" and "%d" as synonymous (thus not
having to worry about which should be used for an `int32_t`.  Once 64-bit
values came on scene, a printf implementation could use:

   int printf(const char*format, ... {long long, unsigned long long,
              long double, void*});

if desired to make all the integer foramts interchangeable.  To avoid
problems with vsprintf etc., the Standard should probably also specify a
standard macro, so that code which was going to use vprintf could use
a prototype of e.g.

    int consoleprintf(int color, const char *format, __PRINTF_VARGS__);

and know that the variable arguments would yield a va_list suitable for
use with vsprintf.

On platforms where it's more efficient to work with extended-precision types
than packed types, the only reason to pass floating-point numbers as 64-bit
values rather than 80-bit types would be that one has a printf method that
only knows how to handle the former.  Otherwise, it would be more efficient
to have printf *only* accept 80-bit types than for it to need to process both
64-bit and 80-bit types.

> Certainly some code gets format strings wrong.  I'm skeptical that most
> code does so.  (I'm not sure how much code even uses long double; double
> is sufficient for most purposes.)
> 
> C99 made "%lf" synonymous with "%f".

Not a whole lot of code uses "long double", but even less gets the format
string right.

> I think making double and long double the same size is mostly a Windows
> thing; gcc gives long double a greater size, range, and precision than
> double.

The sensible behavior IMHO would have been to have "long double" be the type
on which "double" calculations get performed, and "long float" be the type
on which "float" computations get performed.  A simple clear and unambiguous
rule which would have avoided a lot of problems if printf problems hadn't
messed things up.

> Pre-ANSI C only had float and double.  ANSI added long double.
> On some implementations, long double might be substantially less
> efficient than double, so promoting double arguments to long double
> could be inefficient.

Platforms were "double" is the most efficient type for computations should
make "long double" synonymous with "double" and perform computations in that
type.  If they offer some slower higher-precision type, that should be a
separate compiler intrinsic.

> Remembering to use "%f" for double and "%Lf" for long double should be
> no more difficult than remembering to use "%d", "%ld", and "%lld" for
> int, long, and long long.

Someone who has been taught that one is uppercase and one is lowercase will
remember that, and I understand the historical reasons things are what they
are, but could you really blame someone who, given the analogy problem:

   (int   ) is to (long int   ) as "%d" is to "%ld"
   (double) is to (long double) as "%f" is to ?

figures that the answer should be "%lf"?  I've seen plenty of code like that
written by people whose compilers treated double and long double as synonymous
but nonetheless recognized the IEEE-intended proper use of "long double" for
storing intermediate results.

[toc] | [prev] | [next] | [standalone]


#70192

FromKeith Thompson <kst-u@mib.org>
Date2015-09-10 15:17 -0700
Message-ID<ln37ylor6c.fsf@kst-u.example.com>
In reply to#70191
supercat@casperkitty.com writes:
> On Thursday, September 10, 2015 at 2:47:44 PM UTC-5, Keith Thompson wrote:
>> ANSI (and ISO) specified that float arguments are promoted to double,
>> and double and long double arguments are passed as they are.  The rules
>> are unambiguous.
>
> Unambiguous does not mean helpful, and the ambiguity is not so much in the
> prototype itself, but numeric promotions elsewhere.  On some platforms
> (*especially those without floating-point units*), the most efficient way
> to perform operations on floating-point values is to convert all values to
> an extended-precision type and perform computations with that type, and
> then coerce the value as needed when assigning it into a variable or
> parameter.  If the language makes the extended precision type available to
> the programmer, this approach allows floating-point calculations to be faster,
> easier, and more understandable than otherwise possible.
>
> The problem arises with code like:
>
>     double d1 = 123456789.0;
>     double d2 = 123456789.1 - d1;
>
> From a semantic standpoint, if the compiler can subtract d1 from
> 123456789.09999999999999999991, yielding 0.09999999999999999991 just as
> cheaply as it can subtract from 123456789.099999994039535522, the former
> is far more likely to be the desired behavior.  That creates a problem,
> though, of what the type of the numeric literal should be.

The type of an unsuffixed floating-point constant is double.  If you
want long double, use an "L" suffix.

> floating-point arguments were passed to printf the same way, as had been
> the case in C as originally designed, the exact type of the value wouldn't
> matter, but the incompatible treatment of "long double" adds many more
> complications.

Adding a third floating-point type added some complications -- not,
IMHO, many of them.

>> Would you want to make it impossible to pass both double and long double
>> arguments to the same variadic function?  For example, this is perfectly
>> legal:
>> 
>>     float f = 1.0;
>>     double d = 2.0;
>>     long double ld = 3.0;
>>     printf("%f %f %Lf\n", f, d, ld);
>
> Nothing wrong with that, but this should be legal *AS WELL*
>
>      printf("%f %f %f\n", f, d, ld);
>
> If a library's ABI for printf requires that it receive floating-point values
> in 64-bit format, the long double should be rounded down to that format; if
> the ABI requires 80-bit values, the double should be extended to 80 bits.

So for some implementations, you suggest that I *can't* pass a long
double value to printf without losing precision?  No thanks.

[...]

> On platforms where it's more efficient to work with extended-precision types
> than packed types, the only reason to pass floating-point numbers as 64-bit
> values rather than 80-bit types would be that one has a printf method that
> only knows how to handle the former.  Otherwise, it would be more efficient
> to have printf *only* accept 80-bit types than for it to need to process both
> 64-bit and 80-bit types.
>
>> Certainly some code gets format strings wrong.  I'm skeptical that most
>> code does so.  (I'm not sure how much code even uses long double; double
>> is sufficient for most purposes.)
>> 
>> C99 made "%lf" synonymous with "%f".
>
> Not a whole lot of code uses "long double", but even less gets the format
> string right.

Citation needed.  (No doubt you can produce individual examples; I'm
looking for something more general.)

It's not that difficult to read the documentation.  I'm certainly aware
that a lot of people don't, but I'm not convinced that it's a widespread
problem.

[...]

> Platforms were "double" is the most efficient type for computations should
> make "long double" synonymous with "double" and perform computations in that
> type.  If they offer some slower higher-precision type, that should be a
> separate compiler intrinsic.

Currently, platforms where double is the most efficient floating-point
type can provide a wider long double type with greater precision and
range and slower performance.

[...]

> Someone who has been taught that one is uppercase and one is lowercase will
> remember that, and I understand the historical reasons things are what they
> are, but could you really blame someone who, given the analogy problem:
>
>    (int   ) is to (long int   ) as "%d" is to "%ld"
>    (double) is to (long double) as "%f" is to ?
>
> figures that the answer should be "%lf"?  I've seen plenty of code like that
> written by people whose compilers treated double and long double as synonymous
> but nonetheless recognized the IEEE-intended proper use of "long double" for
> storing intermediate results.

Sure, programmers make mistakes.  I just don't think that the current
specification (which is consistent and unambiguous) is so confusing that
we need to change the language as radically as you suggest.  And I'm
fairly sure your proposed changes would break existing code, so they're
never going to happen.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
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"

[toc] | [prev] | [next] | [standalone]


#70197

Fromsupercat@casperkitty.com
Date2015-09-10 16:02 -0700
Message-ID<893e3f42-e89d-4c9b-bdfe-cb9e577c3c3b@googlegroups.com>
In reply to#70192
On Thursday, September 10, 2015 at 5:17:31 PM UTC-5, Keith Thompson wrote:
> > From a semantic standpoint, if the compiler can subtract d1 from
> > 123456789.09999999999999999991, yielding 0.09999999999999999991 just as
> > cheaply as it can subtract from 123456789.099999994039535522, the former
> > is far more likely to be the desired behavior.  That creates a problem,
> > though, of what the type of the numeric literal should be.
> 
> The type of an unsuffixed floating-point constant is double.  If you
> want long double, use an "L" suffix.

Which do you think is more likely--that the programmer wants a result of
0.09999999999999999991, or 0.099999994039535522?  If the floating-point type
the platform handles most efficiently can represent the more precise value,
is there any reason a programmer shouldn't want it?

> > If a library's ABI for printf requires that it receive floating-point values
> > in 64-bit format, the long double should be rounded down to that format; if
> > the ABI requires 80-bit values, the double should be extended to 80 bits.
> 
> So for some implementations, you suggest that I *can't* pass a long
> double value to printf without losing precision?  No thanks.

If one wants to use a library that can't handle 80-bit floating-point values,
is it better to have "long double" get passed as the nearest 64-bit equivalent
or to have it get passed as something the library can't process at all?  The
only situation where I can see the current situation as being better than one
where double eagerly promotes to long double, which gets passed as whatever
type is specified in the ABI for the library one is using, would be if one had
a library that supported both 64-bit and 80-bit types, but was designed for
platforms where extended types were slower and would thus not be used by
default.  If slower extended types had been called something other than "long
double", however, that case could be accommodated by something like e.g.

   int printf(const char*format, ... {long long, unsigned long long,
              double, __extended, void*});

in which case code which didn't care about whether a value was 64 bits or 80
bits would use "long double" and "%f", while code which needed an 80-bit
type would use "__extended" and "%Lf".  If "long double" happened to be 80
bits, it would get printed as 64, but in most cases where code would have
been happy with 64 bits, that shouldn't be a problem (on machines where
floating-point operations are performed using 80-bit math, it's important
that variables be able to hold intermediate values with absolute precision,
but "printf" is generally used for final values rather than intermediate
values and most implementations aren't absolutely precise anyway.

> Citation needed.  (No doubt you can produce individual examples; I'm
> looking for something more general.)

Somewhat tautological, since it wouldn't be possible for the amount of code
that gets the format string right to exceed the amount using "long double";
I know that I've sometimes seen code use "%lf" to print "long double", and
sometimes seen code which used "%f"; I think there are some stack overflow
questions on the subject, so it's clearly tripping some people up.

> It's not that difficult to read the documentation.  I'm certainly aware
> that a lot of people don't, but I'm not convinced that it's a widespread
> problem.

Can you offer any other reason why a compiler vendor wouldn't support a
proper 80-bit `long double` type on platforms where computations on that
type are faster than on any other?  Storage efficient is generally a
non-issue with such types, since from both a semantic and performance
standpoint the benefits of such types are greatest in situations where
they would be kept in registers anyhow.

> > Platforms were "double" is the most efficient type for computations should
> > make "long double" synonymous with "double" and perform computations in that
> > type.  If they offer some slower higher-precision type, that should be a
> > separate compiler intrinsic.
> 
> Currently, platforms where double is the most efficient floating-point
> type can provide a wider long double type with greater precision and
> range and slower performance.

Indeed that's possible, but how numerous are the use cases for slow
extended-precision types, compared with the use cases for floating-point
types that trade speed for space?

> Sure, programmers make mistakes.  I just don't think that the current
> specification (which is consistent and unambiguous) is so confusing that
> we need to change the language as radically as you suggest.  And I'm
> fairly sure your proposed changes would break existing code, so they're
> never going to happen.

The C language has already sufficiently destroyed floating-point semantics
that I see no reason to expect them to ever recover.  My main point was that
if ANSI had allowed variadic functions to specify how they expect to receive
their floating-point types, and defined the relationship among the four fast
floating-point types as I described, the language could have offered better
semantics and performance than it was able to offer as a consequence of the
failure to define variadic argument coercion.

Incidentally, I still think a variadic-argument coercion feature would be
useful for mitigating problems porting code that expects "%ld" to output a
32-bit value (it used to work on both 16-bit and 32-bit systems) to systems
where "long" is 64 bits, but I don't see any realistic path toward the
adoption of such a thing.

[toc] | [prev] | [next] | [standalone]


#70201

FromKeith Thompson <kst-u@mib.org>
Date2015-09-10 17:31 -0700
Message-ID<lnvbbhn6e1.fsf@kst-u.example.com>
In reply to#70197
supercat@casperkitty.com writes:
> On Thursday, September 10, 2015 at 5:17:31 PM UTC-5, Keith Thompson wrote:
[...]
>> The type of an unsuffixed floating-point constant is double.  If you
>> want long double, use an "L" suffix.
>
> Which do you think is more likely--that the programmer wants a result of
> 0.09999999999999999991, or 0.099999994039535522?  If the floating-point type
> the platform handles most efficiently can represent the more precise value,
> is there any reason a programmer shouldn't want it?

If you write code that uses double, you've indicated that that's the
precision you want.  If you want more precision than that, you can use
long double.

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.

>> > If a library's ABI for printf requires that it receive
>> > floating-point values in 64-bit format, the long double should be
>> > rounded down to that format; if the ABI requires 80-bit values, the
>> > double should be extended to 80 bits.
>> 
>> So for some implementations, you suggest that I *can't* pass a long
>> double value to printf without losing precision?  No thanks.
>
> If one wants to use a library that can't handle 80-bit floating-point
> values, is it better to have "long double" get passed as the nearest
> 64-bit equivalent or to have it get passed as something the library
> can't process at all?

If the implementation has an 80-bit long double type, then a library
that doesn't support it is non-conforming.

[...]

>> Citation needed.  (No doubt you can produce individual examples; I'm
>> looking for something more general.)
>
> Somewhat tautological, since it wouldn't be possible for the amount of
> code that gets the format string right to exceed the amount using
> "long double"; I know that I've sometimes seen code use "%lf" to print
> "long double", and sometimes seen code which used "%f"; I think there
> are some stack overflow questions on the subject, so it's clearly
> tripping some people up.

I don't think Stack Overflow questions are representative of real-world
code.  A lot of them are from inexperienced beginners.

>> It's not that difficult to read the documentation.  I'm certainly aware
>> that a lot of people don't, but I'm not convinced that it's a widespread
>> problem.
>
> Can you offer any other reason why a compiler vendor wouldn't support a
> proper 80-bit `long double` type on platforms where computations on that
> type are faster than on any other?  Storage efficient is generally a
> non-issue with such types, since from both a semantic and performance
> standpoint the benefits of such types are greatest in situations where
> they would be kept in registers anyhow.

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".)

[...]

> The C language has already sufficiently destroyed floating-point
> semantics that I see no reason to expect them to ever recover.

It doesn't seem at all destroyed to me.

[...]

> Incidentally, I still think a variadic-argument coercion feature would
> be useful for mitigating problems porting code that expects "%ld" to
> output a 32-bit value (it used to work on both 16-bit and 32-bit
> systems) to systems where "long" is 64 bits, but I don't see any
> realistic path toward the adoption of such a thing.

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 <inttypes.h>.  I don't think it's
necessary to mess with the way arguments to variadic functions are
promoted.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
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"

[toc] | [prev] | [next] | [standalone]


#70285

Fromsupercat@casperkitty.com
Date2015-09-11 15:43 -0700
Message-ID<cd7de70a-3540-427e-a7ad-805133682268@googlegroups.com>
In reply to#70201
On Thursday, September 10, 2015 at 7:31:45 PM UTC-5, Keith Thompson wrote:
> If you write code that uses double, you've indicated that that's the
> precision you want.  If you want more precision than that, you can use
> long double.

Generally, I would expect that someone would want numeric literals to supply
the same level of precision as computations.  On a system where operations on
64-bit double values are carried out with 64 bits of precision, literals
should likewise have 64 bits of precision.  On systems where operations on
64-bit values are carried out with 80 bits of precision, literals should likewise have 80 bits of precision.

On systems which naturally promote numerical values to 80 bits for purposes
of computation, the optimal code from a performance standpoint will be
equivalent to either:

    long double temp = 123456789.09999999999999999991L;
    double d2 = 123456789.1 - d1;
or
    long double temp = 123456789.099999994039535522123456789.0L;
    double d2 = 123456789.1 - d1;

From an efficiency standpoint both are equivalent, and will be faster than:

    long double temp = 123456789.1;
    double d2 = 123456789.1 - d1;

In cases where computations where the subtraction would be performed using
64-bit values, a programmer would have no reason to care whether the constant
was 64 bits or 80 bits, but in cases where computations get promoted, such
distinctions are important.

> 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.
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.

> 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", I
would suggest that it would be be better to round values when using "printf"
but be able to guarantee that:

    double sum(double a, double b, double c)
    {
      long double ab = a+b;
      return ab+c;
    }

will yield the same result as:

    double sum(double a, double b, double c)
    {
      return a+b+c;
    }

than to have the former code perform a rounding step which is omitted in the
latter.

> 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, but programmers want stuff to work.  Though in fairness, I don't
think the MS decision is purely a function of "printf" but also a result
of other things that were compelled by the "printf" issue [such as making
literals default to inferior precision even though, with "long double"
defined as intended, using "long double" [not necessarily extended] precision
for literals would have been no more expensive than rounding to double.

> > The C language has already sufficiently destroyed floating-point
> > semantics that I see no reason to expect them to ever recover.
> 
> It doesn't seem at all destroyed to me.

Floating-point math still exists, but it's needlessly slow, cumbersome, and
imprecise.  Use of extended-precision types for computed temporary values
makes it easy to compute the sum of a group of numbers without adding up to
a full ULP of round-off error at every step.  While it's possible even without
extended-precision types to add 256 numbers with only about 4ULP of round-off
error, adding 256 numbers with extended-precision types is much simpler and
yields a worst-case round-off error below 0.51ULP.

See Kahan's paper http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf for some
discussion of how floating-point semantics should work, as compared with the
approach that seems to have been taken in the 1990s.

> 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 <inttypes.h>.  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.

[toc] | [prev] | [next] | [standalone]


#70287

FromKeith Thompson <kst-u@mib.org>
Date2015-09-11 16:23 -0700
Message-ID<ln1te4mtgo.fsf@kst-u.example.com>
In reply to#70285
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 <math.h>.  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 <inttypes.h>.  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  <http://www.ghoti.net/~kst>
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"

[toc] | [prev] | [next] | [standalone]


#70313

FromRobert Wessel <robertwessel2@yahoo.com>
Date2015-09-11 23:33 -0500
Message-ID<sma7va5omuiags5a3v5dg3b7t47fvnilnd@4ax.com>
In reply to#70201
On Thu, 10 Sep 2015 17:31:34 -0700, Keith Thompson <kst-u@mib.org>
wrote:

>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).


My understanding has always been that they did it for compatibility
with other platforms running WinNT (IOW, there was no 80-bit FP type
on MIPS).

[toc] | [prev] | [next] | [standalone]


#70314

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-11 21:44 -0700
Message-ID<kfnk2rwi6v4.fsf@x-alumni2.alumni.caltech.edu>
In reply to#70197
supercat@casperkitty.com writes:

> [snip]
>
> The C language has already sufficiently destroyed floating-point
> semantics that I see no reason to expect them to ever recover.  My
> main point was that if ANSI had allowed variadic functions to
> specify how they expect to receive their floating-point types, and
> defined the relationship among the four fast floating-point types
> as I described, the language could have offered better semantics
> and performance than it was able to offer as a consequence of the
> failure to define variadic argument coercion.

Let me make sure I understand you.  Based on your comments in
several postings, I believe you have three complaints:

   1. The type of floating point constants should default to
      maximum precision, not double.

   2. For variadic functions, the existing promotion rules
      lead to many mistakes in terms of type mismatches (ie,
      for floating-point values - for now I'm ignoring the
      questions for non-floating-point values).

   3. For floating-point operations, the types/representations
      of intermediate values is either underspecified or
      specified poorly (I'm not sure which you think is the
      case).

Is this an accurate summary of what you been saying (ie, with
respect to floating-point)?  Is there something I've missed
or some other complaint you would like to list?

[toc] | [prev] | [next] | [standalone]


#70356

Fromsupercat@casperkitty.com
Date2015-09-12 09:02 -0700
Message-ID<fc530971-50ab-438c-86f4-fc84b191eb41@googlegroups.com>
In reply to#70314
On Friday, September 11, 2015 at 11:44:57 PM UTC-5, Tim Rentsch wrote:
> Let me make sure I understand you.  Based on your comments in
> several postings, I believe you have three complaints:
> 
>    1. The type of floating point constants should default to
>       maximum precision, not double.

The type of floating-point constants should default to the precision with
which operations on "double" will be performed; further, if a language
supports types of higher precision, the compiler should squawk at most
attempts to use lower-precision values in contexts requiring higher-precision
values (the most notable cases when such conversions should be allowed would
be when the lower-precision value is either a variable of lower-precision,
a constant which is suffixed for the lower-precision type, or typecast
expression of the *lower* precision type.  IMHO, except when __extended is
the same as the type used for "double" division, I would posit that given
code

    double one = 1.0; ten = 10.0;
    __extended foo = one/ten;

there's no way to say with anything near certainty whether the intended
computation is

    __extended foo = (double)(one/ten);
      // Round to 64-bit double, even if computation uses 80
or
    __extended foo = (__extended)one/ten;
      // Force computation to be done as 80 bits
or
    __extended foo = (long_double)(one/ten);
      // Explicitly accept default behavior of division

and if I had my druthers, compilers would never have always required one of
the latter formulations.

>    2. For variadic functions, the existing promotion rules
>       lead to many mistakes in terms of type mismatches (ie,
>       for floating-point values - for now I'm ignoring the
>       questions for non-floating-point values).

Not only do they lead to mistakes--they make the type of intermediate values
*matter* in ways that they should not.  Given

    double a,b,c;
    printf("%f %f %f %f %f", a, b, c, a+b, a+b+c);

it should be possible to rewrite the code as:

    double a,b,c;
    some_type ab = a+b;
    printf("%f %f %f %f %f", a, b, c, ab, ab+c);

with equivalent behavior.  On most machines which had an 80-bit type, and on
machines which don't support an 80-bit type, the most logical type would be
"long double", but for the problems of "printf".

>    3. For floating-point operations, the types/representations
>       of intermediate values is either underspecified or
>       specified poorly (I'm not sure which you think is the
>       case).

While there is some usefulness to specifying whether the type used for
computations is 64 bits or 80 bits, what's more important is that there be
a means of declaring variables *of that type*, and that a means exist by
which a variadic function can accept variables of that type interchangeably
with variables of type double.

> Is this an accurate summary of what you been saying (ie, with
> respect to floating-point)?  Is there something I've missed
> or some other complaint you would like to list?

Pretty nice summary.  In the days prior to IEEE-754, many compilers used an
extended-precision type for computations but allowed no means by which
programmers could create variables of that type to store intermediate
computations, a situation which IEEE-754 was intended to correct by
defining an explit extended-precision type.  The fact that C couldn't make
variables of such a type compatible with expressions involving computations
on "double" meant that many compilers responded by making the type unavailable
to programmers--**RECREATING THE VERY PROBLEM THAT IEEE-754 WAS SUPPOSED TO
CORRECT**.

[toc] | [prev] | [next] | [standalone]


#71231

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-26 15:00 -0700
Message-ID<kfnio6wg7sb.fsf@x-alumni2.alumni.caltech.edu>
In reply to#70356
supercat@casperkitty.com writes:

> On Friday, September 11, 2015 at 11:44:57 PM UTC-5, Tim Rentsch wrote:
>> Let me make sure I understand you.  Based on your comments in
>> several postings, I believe you have three complaints:
>>
>>    1.  The type of floating point constants should default to
>>       maximum precision, not double.
>
> The type of floating-point constants should default to the
> precision with which operations on "double" will be performed;

That type may not be well-defined, or indeed there may be no such
type.  I believe the latter in fact holds in some current
implementations.

> further, if a language supports types of higher precision, the
> compiler should squawk at most attempts to use lower-precision
> values in contexts requiring higher-precision values [snip
> elaboration]

That is a QOI issue, not a language issue.  The C standard
deliberately avoids QOI issues.

>>    2.  For variadic functions, the existing promotion rules
>>       lead to many mistakes in terms of type mismatches (ie,
>>       for floating-point values - for now I'm ignoring the
>>       questions for non-floating-point values).
>
> Not only do they lead to mistakes--they make the type of
> intermediate values *matter* in ways that they should not.  Given
>
>     double a,b,c;
>     printf("%f %f %f %f %f", a, b, c, a+b, a+b+c);
>
> it should be possible to rewrite the code as:
>
>     double a,b,c;
>     some_type ab = a+b;
>     printf("%f %f %f %f %f", a, b, c, ab, ab+c);
>
> with equivalent behavior.  On most machines which had an 80-bit
> type, and on machines which don't support an 80-bit type, the most
> logical type would be "long double", but for the problems of
> "printf".

You're double dipping here.  These are two separate issues.
Moreover the worry about arguments to printf() can be
addressed fairly thoroughly using existing compiler warnings.
I believe that mechanism is also available for use with
other (ie, user-defined) functions, although I don't have
any direct experience with that.  Generally I try to avoid
using (user-defined) variadic functions.

>>    3.  For floating-point operations, the types/representations
>>       of intermediate values is either underspecified or
>>       specified poorly (I'm not sure which you think is the
>>       case).
>
> While there is some usefulness to specifying whether the type
> used for computations is 64 bits or 80 bits, what's more
> important is that there be a means of declaring variables *of
> that type*,

Again that is not a well-defined notion, nor is such a type
guaranteed to exist.  If it's important not to lose precison in
some computations, just use long double for those computations.

> and that a means exist by which a variadic function can accept
> variables of that type interchangeably with variables of type
> double.

There's an easy way to do that - expect long double, and cast
arguments to long double.  Variadic functions are a crutch;  a
useful crutch in some cases, but a crutch nonetheless.  I don't
think much effort should be put into enhancing them;  rather we
should seek out other ways to promote appropriate type safety
and conversions.

>> Is this an accurate summary of what you been saying (ie, with
>> respect to floating-point)?  Is there something I've missed
>> or some other complaint you would like to list?
>
> Pretty nice summary.  In the days prior to IEEE-754, many
> compilers used an extended-precision type for computations but
> allowed no means by which programmers could create variables of
> that type to store intermediate computations, a situation which
> IEEE-754 was intended to correct by defining an explit
> extended-precision type.  The fact that C couldn't make variables
> of such a type compatible with expressions involving computations
> on "double" meant that many compilers responded by making the type
> unavailable to programmers--**RECREATING THE VERY PROBLEM THAT
> IEEE-754 WAS SUPPOSED TO CORRECT**.

I think this reaction is overblown.  The C standard deliberately
adopts flexible requirements, to allow C implementations to be
available on a wide range of hardware.  It also recognizes the
importance of IEEE-754, and tries to provide ways of ensuring
compliance with that.  The complaint you raise here is really
about implementations, not about the language.  It is important
for C that the language requirements be flexible so that C can be
available on just about any hardware platform.  If you're looking
for a language a with higher bar for minimal requirements, maybe
you should consider using Java.

[toc] | [prev] | [next] | [standalone]


#71282

Fromsupercat@casperkitty.com
Date2015-09-27 11:21 -0700
Message-ID<635dbdb3-8a53-4d33-aaa7-42971c400e49@googlegroups.com>
In reply to#71231
On Saturday, September 26, 2015 at 5:01:04 PM UTC-5, Tim Rentsch wrote:
> supercat writes:
> > The type of floating-point constants should default to the
> > precision with which operations on "double" will be performed;
> 
> That type may not be well-defined, or indeed there may be no such
> type.  I believe the latter in fact holds in some current
> implementations.

Thinking about it, it might perhaps have been better to say that unsuffixed
numeric literals should represent things in whatever type they are coerced
to in the context where they appear, with the proviso that implementations
may but are not required to double-round them when coercing to a smaller
value (so that e.g. "float f=16777218.9999999999999999;" would be allowed to
assign either 1677218.0f or 16777220.0f).  Someone who cares which value is
used should specify a number which is within 0.25ulp of the desired value.

> > further, if a language supports types of higher precision, the
> > compiler should squawk at most attempts to use lower-precision
> > values in contexts requiring higher-precision values [snip
> > elaboration]
> 
> That is a QOI issue, not a language issue.  The C standard
> deliberately avoids QOI issues.

To its detriment, IMHO.  Most kinds of protocol specifications make frequent
use of "SHOULD", and recognize the concept of implementations which conform
to the minimal requirements of the specification but are nonetheless to be
regarded as non-normative.  If a language is intended to be used for the
writing of platform-indpendent code, it should highly recommend that any
code whose behavior is supposed to vary from one platform to another should
be written to make that intention clear.

> You're double dipping here.  These are two separate issues.
> Moreover the worry about arguments to printf() can be
> addressed fairly thoroughly using existing compiler warnings.

The behavior of variadic functions creates a distinction between 80-bit values that must be coerced to 64 bits when passed to a variadic function, versus
80-bit values which must be passed to variadic functions as 80-bit values;
I can't think of any other context where the distinction would be relevant.

As for compiler warnings, I don't think warnings about "printf" parameters
became commonplace until compilers started making "long double" as an alias
for "double" even when they used 80-bit intermediate types.

> I believe that mechanism is also available for use with
> other (ie, user-defined) functions, although I don't have
> any direct experience with that.  Generally I try to avoid
> using (user-defined) variadic functions.

GCC allows a function to declare that a variadic function's last parameter
before the "..." should be treated as a printf or scanf format string which
applies to all subsequent parameters.  I know of no other features to tell
a compiler anything about other variadic functions.

> Again that is not a well-defined notion, nor is such a type
> guaranteed to exist.  If it's important not to lose precison in
> some computations, just use long double for those computations.

In many cases, it's often perfectly fine to have multiple expressions all
be performed at higher precision, or all at lower precision, provided that
the rounding is performed consistently.  In cases where either approach will
meet requirements, but one way or the other may be more efficient, I'd
suggest that the choice of approach should be left up to the implementation.

It's certainly true that some implementations with dodgy floating-point
semantics can't really offer any guarantees about when rounding will or will
not occur.  Code where such things matter should reject such implementations.
What I would consider important is defining a means by which code can, with
minimal headache, be written so as to most efficiently meet requirements on
the platforms where behaviors are defined.

> > and that a means exist by which a variadic function can accept
> > variables of that type interchangeably with variables of type
> > double.
> 
> There's an easy way to do that - expect long double, and cast
> arguments to long double.  Variadic functions are a crutch;  a
> useful crutch in some cases, but a crutch nonetheless.  I don't
> think much effort should be put into enhancing them;  rather we
> should seek out other ways to promote appropriate type safety
> and conversions.

If prototypes could provide a list of types for variadic functions and
require that all arguments be coerced to a type on the list (and the
compiler should squawk if any argument cannot be thus coerced) then
functions could safely and simply expect long double without callers
having to typecast them or worry about whether changing the type of
something would break a downstream printf.  Alas, no such feature exists.

BTW, I suspect that it would probably not have taken a whole lot of compiler
code or library code to add a type-safe variadic-argument mechanism, and in
many cases such a mechanism could shrink caller-side code.  For example, what
would now be written as "printf("%d,%d", x, y);" presently requires that the
compiler generate instructions to push the address of the string, x, and y
onto the stack.  A type-safe variadic-argument mechanism could instead simply
push the address of a a template within a structure that would contain
the types and either global or frame-relative addresses of x and y, e.g. if
x was global and y was local, perhaps something like:

    static const struct { int *p1; char dat[7];} pxy =
       {&x, "\006\302\001\001,\202\020"};
    __printf( &(pxy.dat) );

> I think this reaction is overblown.  The C standard deliberately
> adopts flexible requirements, to allow C implementations to be
> available on a wide range of hardware.  It also recognizes the
> importance of IEEE-754, and tries to provide ways of ensuring
> compliance with that.  The complaint you raise here is really
> about implementations, not about the language.  It is important
> for C that the language requirements be flexible so that C can be
> available on just about any hardware platform.  If you're looking
> for a language a with higher bar for minimal requirements, maybe
> you should consider using Java.

My complaint is that C fails to define a means by which programs can be
written in such a way as to yield correct semantically-correct behavior
on platforms with any of the most common forms of hardware floating-point
semantics without having to force programs to use semantics that might be
slower than the default.

[toc] | [prev] | [next] | [standalone]


#71439

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-29 10:10 -0700
Message-ID<kfn8u7pcfs1.fsf@x-alumni2.alumni.caltech.edu>
In reply to#71282
supercat@casperkitty.com writes:

> On Saturday, September 26, 2015 at 5:01:04 PM UTC-5, Tim Rentsch wrote:
>> supercat writes:
>>> The type of floating-point constants should default to the
>>> precision with which operations on "double" will be performed;
>>
>> That type may not be well-defined, or indeed there may be no such
>> type.  I believe the latter in fact holds in some current
>> implementations.
>
> Thinking about it, it might perhaps have been better to say that
> unsuffixed numeric literals should represent things in whatever type
> they are coerced to in the context where they appear, with the
> proviso that implementations may but are not required to
> double-round them when coercing to a smaller value (so that
> e.g. "float f=16777218.9999999999999999;" would be allowed to assign
> either 1677218.0f or 16777220.0f).  Someone who cares which value is
> used should specify a number which is within 0.25ulp of the desired
> value.
>
>>> further, if a language supports types of higher precision, the
>>> compiler should squawk at most attempts to use lower-precision
>>> values in contexts requiring higher-precision values [snip
>>> elaboration]
>>
>> That is a QOI issue, not a language issue.  The C standard
>> deliberately avoids QOI issues.
>
> To its detriment, IMHO.  Most kinds of protocol specifications make
> frequent use of "SHOULD", and recognize the concept of
> implementations which conform to the minimal requirements of the
> specification but are nonetheless to be regarded as non-normative.
> If a language is intended to be used for the writing of
> platform-indpendent code, it should highly recommend that any code
> whose behavior is supposed to vary from one platform to another
> should be written to make that intention clear.
>
>> You're double dipping here.  These are two separate issues.
>> Moreover the worry about arguments to printf() can be
>> addressed fairly thoroughly using existing compiler warnings.
>
> The behavior of variadic functions creates a distinction between
> 80-bit values that must be coerced to 64 bits when passed to a
> variadic function, versus 80-bit values which must be passed to
> variadic functions as 80-bit values;  I can't think of any other
> context where the distinction would be relevant.
>
> As for compiler warnings, I don't think warnings about "printf"
> parameters became commonplace until compilers started making "long
> double" as an alias for "double" even when they used 80-bit
> intermediate types.
>
>> I believe that mechanism is also available for use with
>> other (ie, user-defined) functions, although I don't have
>> any direct experience with that.  Generally I try to avoid
>> using (user-defined) variadic functions.
>
> GCC allows a function to declare that a variadic function's last
> parameter before the "..." should be treated as a printf or scanf
> format string which applies to all subsequent parameters.  I know of
> no other features to tell a compiler anything about other variadic
> functions.
>
>> Again that is not a well-defined notion, nor is such a type
>> guaranteed to exist.  If it's important not to lose precison in
>> some computations, just use long double for those computations.
>
> In many cases, it's often perfectly fine to have multiple
> expressions all be performed at higher precision, or all at lower
> precision, provided that the rounding is performed consistently.  In
> cases where either approach will meet requirements, but one way or
> the other may be more efficient, I'd suggest that the choice of
> approach should be left up to the implementation.
>
> It's certainly true that some implementations with dodgy
> floating-point semantics can't really offer any guarantees about
> when rounding will or will not occur.  Code where such things matter
> should reject such implementations.  What I would consider important
> is defining a means by which code can, with minimal headache, be
> written so as to most efficiently meet requirements on the platforms
> where behaviors are defined.
>
>>> and that a means exist by which a variadic function can accept
>>> variables of that type interchangeably with variables of type
>>> double.
>>
>> There's an easy way to do that - expect long double, and cast
>> arguments to long double.  Variadic functions are a crutch;  a
>> useful crutch in some cases, but a crutch nonetheless.  I don't
>> think much effort should be put into enhancing them;  rather we
>> should seek out other ways to promote appropriate type safety
>> and conversions.
>
> If prototypes could provide a list of types for variadic functions
> and require that all arguments be coerced to a type on the list (and
> the compiler should squawk if any argument cannot be thus coerced)
> then functions could safely and simply expect long double without
> callers having to typecast them or worry about whether changing the
> type of something would break a downstream printf.  Alas, no such
> feature exists.
>
> BTW, I suspect that it would probably not have taken a whole lot of
> compiler code or library code to add a type-safe variadic-argument
> mechanism, and in many cases such a mechanism could shrink
> caller-side code.  For example, what would now be written as
> "printf("%d,%d", x, y);" presently requires that the compiler
> generate instructions to push the address of the string, x, and y
> onto the stack.  A type-safe variadic-argument mechanism could
> instead simply push the address of a a template within a structure
> that would contain the types and either global or frame-relative
> addresses of x and y, e.g. if x was global and y was local, perhaps
> something like:
>
>     static const struct { int *p1; char dat[7];} pxy =
>        {&x, "\006\302\001\001,\202\020"};
>     __printf( &(pxy.dat) );
>
>> I think this reaction is overblown.  The C standard deliberately
>> adopts flexible requirements, to allow C implementations to be
>> available on a wide range of hardware.  It also recognizes the
>> importance of IEEE-754, and tries to provide ways of ensuring
>> compliance with that.  The complaint you raise here is really
>> about implementations, not about the language.  It is important
>> for C that the language requirements be flexible so that C can be
>> available on just about any hardware platform.  If you're looking
>> for a language a with higher bar for minimal requirements, maybe
>> you should consider using Java.
>
> My complaint is that C fails to define a means by which programs can
> be written in such a way as to yield correct semantically-correct
> behavior on platforms with any of the most common forms of hardware
> floating-point semantics without having to force programs to use
> semantics that might be slower than the default.

Speaking generically it seems like what you want is stronger
guarantees (ie, in the ISO C standard) both about performance and
between implementations.  Neither of those is going to happen.  I
don't know that I have anything further to add to the discussion.

[toc] | [prev] | [next] | [standalone]


#69605

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-09-06 13:41 +0100
Message-ID<87pp1vhg8w.fsf@bsb.me.uk>
In reply to#69594
"James Harris" <james.harris.1@gmail.com> writes:

> (Going back to an old thread)
>
> "Rick C. Hodgin" <rick.c.hodgin@gmail.com> wrote in message
> news:1fe6466f-8b9c-40e6-8ce3-a5209c08fa7a@googlegroups.com...
>> On Monday, July 6, 2015 at 12:50:42 PM UTC-4, Bart wrote:
>>> On 06/07/2015 17:04, Rick C. Hodgin wrote:
>>> > In 2015, what suggestions would you have for changing anything >
>>> about
>>> > the format specifiers used in the printf functions?  Leave them as
>>> > they are?  Or change this or that about them?
>
> The biggest problem with printf specifiers, IMO, is that they only
> work with a fixed set of data types, those which are defined by the
> specification. That's fine if you want to print one of those but not
> for user-defined types.
>
> I would make a similar comment about formatting. The inbuilt
> formatting options may not cover how you want the value to be
> rendered.
>
> Of course, you could use a function to render a value into a malloc'd
> buffer and then print it with %s. But then you'd need to remember to
> free the buffer, and it is unusual in C to have a function return an
> allocated buffer. So how about a conversion specifier which printed as
> %s but then called free() on the result? Would that be feasible?
>
> Example:
>
>  printf("Values = %M, %i\n", mydatatype_render(p), i);
>
> That could possibly be used for *any* printing that was not supplied
> by the standard format specifiers.
>
> Is it worth the addition over %s? I think so, yes.

Maybe.  The alternatives are not awful:

  const char *rep = mydatatype_render(p);
  printf("Values = %s, %i\n", rep ? rep : "<out of memory!>", i);
  free(rep);

is not that much more complicated, and gives more control when handling
allocation failures.  Similarly

  char buf[get_rep_size(p)];
  printf("Values = %M, %i\n", mydatatype_render(buf, p), i);

is also sometimes suitable and involves no malloc at all.

I think a better solution would be to standardise a mechanism to extend
printf formats.  You could then write your own %M but also more
type-specific formats.  Of course that's more complicated to it also
raises the question of whether it's worth the addition.  Whilst I like
both ideas, I am not well-placed to evaluate the costs and benefits of
standardising wither.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#69738

FromRobert Wessel <robertwessel2@yahoo.com>
Date2015-09-07 00:23 -0500
Message-ID<4p7quah1eu0pv1j9g9v9povmjro918ma55@4ax.com>
In reply to#69605
On Sun, 06 Sep 2015 13:41:35 +0100, Ben Bacarisse
<ben.usenet@bsb.me.uk> wrote:

>"James Harris" <james.harris.1@gmail.com> writes:
>
>> (Going back to an old thread)
>>
>> "Rick C. Hodgin" <rick.c.hodgin@gmail.com> wrote in message
>> news:1fe6466f-8b9c-40e6-8ce3-a5209c08fa7a@googlegroups.com...
>>> On Monday, July 6, 2015 at 12:50:42 PM UTC-4, Bart wrote:
>>>> On 06/07/2015 17:04, Rick C. Hodgin wrote:
>>>> > In 2015, what suggestions would you have for changing anything >
>>>> about
>>>> > the format specifiers used in the printf functions?  Leave them as
>>>> > they are?  Or change this or that about them?
>>
>> The biggest problem with printf specifiers, IMO, is that they only
>> work with a fixed set of data types, those which are defined by the
>> specification. That's fine if you want to print one of those but not
>> for user-defined types.
>>
>> I would make a similar comment about formatting. The inbuilt
>> formatting options may not cover how you want the value to be
>> rendered.
>>
>> Of course, you could use a function to render a value into a malloc'd
>> buffer and then print it with %s. But then you'd need to remember to
>> free the buffer, and it is unusual in C to have a function return an
>> allocated buffer. So how about a conversion specifier which printed as
>> %s but then called free() on the result? Would that be feasible?
>>
>> Example:
>>
>>  printf("Values = %M, %i\n", mydatatype_render(p), i);
>>
>> That could possibly be used for *any* printing that was not supplied
>> by the standard format specifiers.
>>
>> Is it worth the addition over %s? I think so, yes.
>
>Maybe.  The alternatives are not awful:
>
>  const char *rep = mydatatype_render(p);
>  printf("Values = %s, %i\n", rep ? rep : "<out of memory!>", i);
>  free(rep);
>
>is not that much more complicated, and gives more control when handling
>allocation failures.  Similarly
>
>  char buf[get_rep_size(p)];
>  printf("Values = %M, %i\n", mydatatype_render(buf, p), i);
>
>is also sometimes suitable and involves no malloc at all.
>
>I think a better solution would be to standardise a mechanism to extend
>printf formats.  You could then write your own %M but also more
>type-specific formats.  Of course that's more complicated to it also
>raises the question of whether it's worth the addition.  Whilst I like
>both ideas, I am not well-placed to evaluate the costs and benefits of
>standardising wither.


I'd be happy with the GCC/glibc extensions for that to be
standardized.

[toc] | [prev] | [next] | [standalone]


#69758

From"James Harris" <james.harris.1@gmail.com>
Date2015-09-07 11:31 +0100
Message-ID<msjotr$sa3$1@dont-email.me>
In reply to#69605
"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message 
news:87pp1vhg8w.fsf@bsb.me.uk...
> "James Harris" <james.harris.1@gmail.com> writes:

...

>> The biggest problem with printf specifiers, IMO, is that they only
>> work with a fixed set of data types, those which are defined by the
>> specification. That's fine if you want to print one of those but not
>> for user-defined types.

...

>> So how about a conversion specifier which printed as
>> %s but then called free() on the result? Would that be feasible?
>>
>> Example:
>>
>>  printf("Values = %M, %i\n", mydatatype_render(p), i);
>>
>> That could possibly be used for *any* printing that was not supplied
>> by the standard format specifiers.
>>
>> Is it worth the addition over %s? I think so, yes.
>
> Maybe.  The alternatives are not awful:
>
>  const char *rep = mydatatype_render(p);
>  printf("Values = %s, %i\n", rep ? rep : "<out of memory!>", i);
>  free(rep);
>
> is not that much more complicated,

Well, consider just two such parameters in the call:

  const char *v0 = T_tostring(s0);
  const char *v1 = T_tostring(s1);
  printf("Values = %s, %s\n, v0 ? v0 : "<out of memory!>",
    v1 ? v1 : "<out of memory!>");
  free(v1);
  free(v0);

and compare that with

  printf("Values = %M, %M\n", x_tostring(s0),
    x_tostring(s1));

I would suggest that the latter is easier to read and easier to write 
and - possibly most importantly - allows the programmer to more easily 
retain focus on the intention of the code rather than the mechanics.

> and gives more control when handling
> allocation failures.

True.

> Similarly
>
>  char buf[get_rep_size(p)];
>  printf("Values = %M, %i\n", mydatatype_render(buf, p), i);
>
> is also sometimes suitable and involves no malloc at all.

Couldn't %s be used like that already?

The static buffer is fine but only as long as the programmer can be 
completely sure that the buffer is large enough - both now and in any 
future upgrades to the mydatatype_render routine, which may be 
impossible to guarantee.

If there is any question at all I think I much prefer the security of 
having the callee return a new buffer. Overflows of static buffers can 
be very expensive and C has been unfairly blamed for too many of them 
over the years.

> I think a better solution would be to standardise a mechanism to 
> extend
> printf formats.  You could then write your own %M but also more
> type-specific formats.  Of course that's more complicated to it also
> raises the question of whether it's worth the addition.  Whilst I like
> both ideas, I am not well-placed to evaluate the costs and benefits of
> standardising wither.

Extending the printf formats sounds good, if feasible. A mechanism would 
probably have to

1. get the printf formatter to call back into user-defined routines,

2. allow the called routines to be passed a qualifying string,

3. allow for codes which were longer than one character (to avoid 
running out of letters),

4. work with the existing less-used aspects of the printf family of 
calls.

It sounds complicated. There could be a way to make it work well but I 
think the "problem" with the printf approach is that the library has to 
know all about the data types and formats that people might want. That 
can be made to work well for built-in types but it has probably been 
extended too far, especially when some current implementations include 
non-standard extensions.

I would welcome a way to extend printf codes if it was as better option 
and could be made to work but at this point in time I think I prefer the 
simple %M idea. With parameters included it allows any kind of 
formatting that a programmer could want and of any data type, and it 
allows knowledge of the data type's internals to be kept in one place. 
If a data type changes then the rendering routine can change what it 
outputs, or it can retain the old format - whatever is appropriate.

James

[toc] | [prev] | [next] | [standalone]


#69759

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-09-07 03:54 -0700
Message-ID<74e9f6e0-bcc4-4e38-976f-af9632af983e@googlegroups.com>
In reply to#69758
On Monday, September 7, 2015 at 11:31:17 AM UTC+1, James Harris wrote:
> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message 
> 
> > Maybe.  The alternatives are not awful:
> >
> >  const char *rep = mydatatype_render(p);
> >  printf("Values = %s, %i\n", rep ? rep : "<out of memory!>", i);
> >  free(rep);
> >
> > is not that much more complicated,
> 
> Well, consider just two such parameters in the call:
> 
>   const char *v0 = T_tostring(s0);
>   const char *v1 = T_tostring(s1);
>   printf("Values = %s, %s\n, v0 ? v0 : "<out of memory!>",
>     v1 ? v1 : "<out of memory!>");
>   free(v1);
>   free(v0);
> 
> and compare that with
> 
>   printf("Values = %M, %M\n", x_tostring(s0),
>     x_tostring(s1));
> 
> I would suggest that the latter is easier to read and easier to write 
> and - possibly most importantly - allows the programmer to more easily 
> retain focus on the intention of the code rather than the mechanics.
> 
Ben's method is acceptable for function foo(), but not for printf.
The reason is that printf is often used for quick debug or other scratch code. 
So the programmer wants to be able to write a call and insert values very
quickly, then comment it out or delete it. It's extremely helpful is everything
is on one line.

[toc] | [prev] | [next] | [standalone]


Page 3 of 8 — ← Prev page 1 2 [3] 4 5 6 7 8  Next page →

Back to top | Article view | comp.lang.c


csiph-web