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


Groups > comp.std.c > #595 > unrolled thread

PRI* considered harmful

Started by"Greg A. Woods" <woods@robohack.org>
First post2011-07-06 19:58 -0700
Last post2011-07-09 20:30 +0100
Articles 20 on this page of 66 — 14 participants

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


Contents

  PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-06 19:58 -0700
    Re: PRI* considered harmful William Ahern <william@wilbur.25thandClement.com> - 2011-07-06 20:38 -0700
      Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-06 22:26 -0700
        Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-07 08:52 +0200
          Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 14:11 -0700
            Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-08 11:58 +0200
          Re: PRI* considered harmful lawrence.jones@siemens.com - 2011-07-07 17:58 -0400
            Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-08 12:02 +0200
        Re: PRI* considered harmful lawrence.jones@siemens.com - 2011-07-07 17:57 -0400
          Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-07 15:42 -0700
            Re: PRI* considered harmful lawrence.jones@siemens.com - 2011-07-08 08:56 -0400
    Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-07 06:36 -0400
      Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 12:59 -0700
        Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-07 14:12 -0700
          Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 15:49 -0700
            Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-07 16:46 -0700
              Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 18:26 -0700
                Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-07 22:35 -0400
                  Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-07 20:58 -0700
                    Re: PRI* considered harmful Wojtek Lerch <wojtek_l@yahoo.ca> - 2011-07-08 00:28 -0400
                    Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-08 07:41 -0400
                      Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-08 23:05 -0700
                        Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 00:50 -0700
                        Re: [incorrectly implementd] PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-09 06:38 -0400
                        Re: PRI* considered harmful Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2011-07-09 21:07 +0200
                    Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-08 09:52 -0700
                Re: PRI* considered harmful Richard Kettlewell <rjk@greenend.org.uk> - 2011-07-08 11:45 +0100
                  Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-08 23:14 -0700
                    Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 00:47 -0700
                    Re: PRI* considered harmful Richard Kettlewell <rjk@greenend.org.uk> - 2011-07-09 10:51 +0100
                    Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-09 06:43 -0400
                Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-08 09:49 -0700
                  Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-08 23:24 -0700
                    Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 00:45 -0700
                      Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 16:18 -0700
                        Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 18:57 -0700
                          Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-13 09:37 -0700
                    Re: PRI* considered harmful James Kuyper <jameskuyper@verizon.net> - 2011-07-09 06:46 -0400
                    Re: PRI* considered harmful Harald van Dijk <truedfx@gmail.com> - 2011-07-09 08:09 -0700
                      Re: PRI* considered harmful Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-07-11 16:00 +0300
                    Re: PRI* considered harmful Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2011-07-09 20:59 +0200
                      Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 12:22 -0700
                        Re: PRI* considered harmful Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2011-07-09 21:32 +0200
                          Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 12:54 -0700
                            Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-09 23:39 +0200
                              Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 16:56 -0700
                            Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 16:52 -0700
                              Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 18:53 -0700
                            Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-10 14:12 +0200
                              Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-11 20:22 +0200
                          Re: PRI* considered harmful Jens Gustedt <Jens.Gustedt@loria.fr> - 2011-07-10 13:57 +0200
                      Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 16:49 -0700
                    Re: PRI* considered harmful Jens Schweikhardt <usenet@schweikhardt.net> - 2011-07-19 19:28 +0000
        Re: PRI* considered harmful Tim Rentsch <txr@alumni.caltech.edu> - 2011-07-07 14:13 -0700
    Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 01:04 -0700
      Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-09 17:23 -0700
        Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-09 19:03 -0700
          Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-11 20:40 +0200
            Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-11 11:56 -0700
              Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-11 21:40 +0200
                Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-11 13:16 -0700
                  Re: PRI* considered harmful Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> - 2011-07-11 23:29 +0200
                    Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-11 14:46 -0700
                Re: PRI* considered harmful "Greg A. Woods" <woods@robohack.org> - 2011-07-12 22:18 -0700
                  Re: PRI* considered harmful Keith Thompson <kst-u@mib.org> - 2011-07-13 09:00 -0700
    Re: PRI* considered harmful Richard Kettlewell <rjk@greenend.org.uk> - 2011-07-09 20:30 +0100

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#685

FromHans-Bernhard Bröker <HBBroeker@t-online.de>
Date2011-07-09 20:59 +0200
Message-ID<97rmoaFc7oU1@mid.dfncis.de>
In reply to#671
On 09.07.2011 08:24, Greg A. Woods wrote:
> Keith Thompson<kst-u@mib.org>  writes:
>> So don't use them.

> It's not _my_ problem -- I try not to use the PRI* macros.  :-)

You appear to have that bass ackwards.  Your problem is that you're 
trying so hard not to use them that you never properly found out whether 
or not there's anything wrong with their specification.

Instead, you rely on random snippets of second- and third-hand knowledge 
to base a wild claim on.

> It's just that I've seen many references to PRId32 on Linux, including
> online manual pages, which show it as "ld"

So what?  "ld" _can_ be a valid definition for that macro.  It's up to 
you, as the person making the big claims here, to prove that on the 
systems you found that definition, it's an incorrect one.

> Well, for me personally (as opposed to all those I see trying to use
> PRI* poorly), the problem extends to every other typedef name that one
> might define in any application which one hopes to be portable and easy
> to maintain.

Defining such stuff from scratch is never portable. It cannot be.

_Using_ portable definitions makes portable code.  That's why int32_t 
and its colleagues exists.  Their definition is unavoidably 
implementation-specific.

> The reason I've harped on PRI* is that their existance would also be
> entirerly unnecessary were something like my proposal implemented,

A proposal that, the way it completely breaks just about every existing 
implementation, not to mention a seriously big number of existing user 
programs for no visible benefit, really does need to be rejected flat out.

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


#687

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 12:22 -0700
Message-ID<lny607w97e.fsf@nuthaus.mib.org>
In reply to#685
Hans-Bernhard Bröker <HBBroeker@t-online.de> writes:
> On 09.07.2011 08:24, Greg A. Woods wrote:
[...]
>> The reason I've harped on PRI* is that their existance would also be
>> entirerly unnecessary were something like my proposal implemented,
>
> A proposal that, the way it completely breaks just about every existing 
> implementation, not to mention a seriously big number of existing user 
> programs for no visible benefit, really does need to be rejected flat out.

How does it break existing implementations?

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#689

FromHans-Bernhard Bröker <HBBroeker@t-online.de>
Date2011-07-09 21:32 +0200
Message-ID<97rom4Fqt5U1@mid.dfncis.de>
In reply to#687
On 09.07.2011 21:22, Keith Thompson wrote:
> Hans-Bernhard Bröker<HBBroeker@t-online.de>  writes:
>> On 09.07.2011 08:24, Greg A. Woods wrote:
> [...]
>>> The reason I've harped on PRI* is that their existance would also be
>>> entirerly unnecessary were something like my proposal implemented,

>> A proposal that, the way it completely breaks just about every existing
>> implementation, not to mention a seriously big number of existing user
>> programs for no visible benefit, really does need to be rejected flat out.

> How does it break existing implementations?

Well, I thought I remembered him proposing to change default argument 
promotions from "at least to (unsigned) int" to "all the way to 
(u)intmax_t".  That would break just about everything.

OTOH, there's a realistic chance I misremember who proposed what in this 
rather lively thread.

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


#690

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 12:54 -0700
Message-ID<lntyavw7qa.fsf@nuthaus.mib.org>
In reply to#689
Hans-Bernhard Bröker <HBBroeker@t-online.de> writes:
> On 09.07.2011 21:22, Keith Thompson wrote:
>> Hans-Bernhard Bröker<HBBroeker@t-online.de>  writes:
>>> On 09.07.2011 08:24, Greg A. Woods wrote:
>> [...]
>>>> The reason I've harped on PRI* is that their existance would also be
>>>> entirerly unnecessary were something like my proposal implemented,
>
>>> A proposal that, the way it completely breaks just about every existing
>>> implementation, not to mention a seriously big number of existing user
>>> programs for no visible benefit, really does need to be rejected flat out.
>
>> How does it break existing implementations?
>
> Well, I thought I remembered him proposing to change default argument 
> promotions from "at least to (unsigned) int" to "all the way to 
> (u)intmax_t".  That would break just about everything.
>
> OTOH, there's a realistic chance I misremember who proposed what in this 
> rather lively thread.

Yes, I remember that somebody proposed changing the promotion
rules; I don't remember who or where.  Certainly that would break
existing code.  It wouldn't necessarily break most printf() calls,
since you could redefine the behavior of printf accordingly; for
example, "%d" would require a possibly promoted intmax_t argument.
But it would certainly break variadic functions that aren't part
of the standard library.

The proposal in the article that started this thread was to add
things like "%Si" to printf, something that could be done in a
backward-compatible manner.  One problem with that proposal is that
it would require integer types with the same size and signedness to
be passed identically as variadic arguments, something the standard
doesn't currently require.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#691

FromMarcin Grzegorczyk <mgrzegor@poczta.onet.pl>
Date2011-07-09 23:39 +0200
Message-ID<ivahqp$j7a$1@dont-email.me>
In reply to#690
Keith Thompson wrote:
> The proposal in the article that started this thread was to add
> things like "%Si" to printf, something that could be done in a
> backward-compatible manner.  One problem with that proposal is that
> it would require integer types with the same size and signedness to
> be passed identically as variadic arguments, something the standard
> doesn't currently require.

The proposal, however, stipulated that the feature would be used like this:

   int128_t foo = -1;
   uint64_t ubar = 1;

   /* ... */

   printf("%Si %Si\n", INTPARAM(foo), INTPARAM(ubar));

where the INTPARAM macro would expand to its argument, preceded by 
another argument that would encode type information in a not necessarily 
portable way (although I note that the C1X generic selection construct 
would make that quite easy to implement in a relatively portable fashion).

(Nota bene: The original article actually proposed INTPARAM to expand to 
three arguments, encoding size and signedness separately; obviously, 
this would be unnecessarily wasteful.)
-- 
Marcin Grzegorczyk

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


#698

From"Greg A. Woods" <woods@robohack.org>
Date2011-07-09 16:56 -0700
Message-ID<87aacnc8kr.fsf@once.weird.com>
In reply to#691
Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> writes:
> (Nota bene: The original article actually proposed INTPARAM to expand
> to three arguments, encoding size and signedness separately;
> obviously, this would be unnecessarily wasteful.)

The use of separate extra parameters for each class of additional
information was more to make the concept easier and quicker to pick up
for evaluation.

Indeed all the necessary additional runtime information could be encoded
into a single int-sized parameter by INTPARAM() or whatever we want to
call it in a final specification.

-- 
						Greg A. Woods
						RoboHack

<woods@robohack.ca>     living on the edge      http://www.robohack.ca/

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


#697

From"Greg A. Woods" <woods@robohack.org>
Date2011-07-09 16:52 -0700
Message-ID<87ei1zc8qn.fsf@once.weird.com>
In reply to#690
Keith Thompson <kst-u@mib.org> writes:
>
> The proposal in the article that started this thread was to add
> things like "%Si" to printf, something that could be done in a
> backward-compatible manner.  One problem with that proposal is that
> it would require integer types with the same size and signedness to
> be passed identically as variadic arguments, something the standard
> doesn't currently require.

Thanks!  I hadn't considered the narrower-than-int issues and the
default promotion rules yet, but I think those too can be hidden
transparently within the INTPARAM() macro.

I think I should probably do a proper implementation and test it more
completely.

-- 
						Greg A. Woods
						RoboHack

<woods@robohack.ca>     living on the edge      http://www.robohack.ca/

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


#700

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 18:53 -0700
Message-ID<lnmxgmx5n3.fsf@nuthaus.mib.org>
In reply to#697
"Greg A. Woods" <woods@robohack.org> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> The proposal in the article that started this thread was to add
>> things like "%Si" to printf, something that could be done in a
>> backward-compatible manner.  One problem with that proposal is that
>> it would require integer types with the same size and signedness to
>> be passed identically as variadic arguments, something the standard
>> doesn't currently require.
>
> Thanks!  I hadn't considered the narrower-than-int issues and the
> default promotion rules yet, but I think those too can be hidden
> transparently within the INTPARAM() macro.

Hmm?  I wasn't talking about narrower-than-int types or promotion
rules at all.  I was talking about your assumption that int and
long are interchangeable as arguments *if they have the same size*.
(You assume that telling printf about the size and signednes of
an argument is enough to allow printf to handle it correctly.)
That's likely to be true for most implementations, but the standard
doesn't guarantee it.  At the very least, some work would be required
to iron out the implications.

> I think I should probably do a proper implementation and test it more
> completely.

Not a bad idea, but no amount of testing will find problems that
might apply to exotic systems to which you don't have access.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#706

FromJens Gustedt <Jens.Gustedt@loria.fr>
Date2011-07-10 14:12 +0200
Message-ID<4E19974A.6070408@loria.fr>
In reply to#690
Am 09.07.2011 21:54, schrieb Keith Thompson:
> Yes, I remember that somebody proposed changing the promotion
> rules; I don't remember who or where.  Certainly that would break
> existing code.

It wouldn't break va_arg code that uses the macros correctly. Storing
in the widest integer type (signed/unsigned) should never loose any
information. So if the va_arg macros would be adapted to cast back to
the desired type all information should be there.

(I don't see immediately if va_arg returns an rvalue or an lvalue. If
it is an lvalue, replace "cast" with a compound literal.)

The same would hold for floating point types or data pointers
transfered via void*.

What would definitively break are functions that are declared without
prototypes. But these are deprecated, aren't they?

>  It wouldn't necessarily break most printf() calls,
> since you could redefine the behavior of printf accordingly; for
> example, "%d" would require a possibly promoted intmax_t argument.

Either that or simply have the va_arg cast back to int

> But it would certainly break variadic functions that aren't part
> of the standard library.

not if they use the va_arg macro properly

Jens

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


#712

FromMarcin Grzegorczyk <mgrzegor@poczta.onet.pl>
Date2011-07-11 20:22 +0200
Message-ID<ivff0b$7f9$1@dont-email.me>
In reply to#706
Jens Gustedt wrote:
> Am 09.07.2011 21:54, schrieb Keith Thompson:
>> Yes, I remember that somebody proposed changing the promotion
>> rules; I don't remember who or where.  Certainly that would break
>> existing code.
>
> It wouldn't break va_arg code that uses the macros correctly.

It would break even code that uses <stdarg.h> correctly, in the sense of 
making it binary incompatible with code compiled under previous rules. 
This is enough for any such proposal to be rejected on the spot.
-- 
Marcin Grzegorczyk

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


#705

FromJens Gustedt <Jens.Gustedt@loria.fr>
Date2011-07-10 13:57 +0200
Message-ID<4E19938F.4080807@loria.fr>
In reply to#689
Am 09.07.2011 21:32, schrieb Hans-Bernhard Bröker:
> Well, I thought I remembered him proposing to change default argument
> promotions from "at least to (unsigned) int" to "all the way to
> (u)intmax_t".  That would break just about everything.
> 
> OTOH, there's a realistic chance I misremember who proposed what in this
> rather lively thread.

You probably refer to my post. All I tried to say in that post is that
the necessity of all this comes from the legacy argument promotion
rules in absence of a prototype, and that things would be much easier
if anything would be just promoted to [u]intmax_t.

Jens

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


#696

From"Greg A. Woods" <woods@robohack.org>
Date2011-07-09 16:49 -0700
Message-ID<87iprbc8v9.fsf@once.weird.com>
In reply to#685
Hans-Bernhard Bröker <HBBroeker@t-online.de> writes:
> 
> A proposal that, the way it completely breaks just about every
> existing implementation

Huh?  Could you give some more details about what you mean?

-- 
						Greg A. Woods
						RoboHack

<woods@robohack.ca>     living on the edge      http://www.robohack.ca/

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


#732

FromJens Schweikhardt <usenet@schweikhardt.net>
Date2011-07-19 19:28 +0000
Message-ID<98m471F8m4U1@mid.individual.net>
In reply to#671
Greg A. Woods <woods@robohack.org> wrote
	in <87r560c6pp.fsf@once.weird.com>:
...
# Well, for me personally (as opposed to all those I see trying to use
# PRI* poorly), the problem extends to every other typedef name that one
# might define in any application which one hopes to be portable and easy
# to maintain.

That's easy to do portably.  For every

    typedef int32_t foo_t;

have a corresponding

    #define PRIFOO PRId32
    #define SCNFOO SCNd32

in your code (or whatever PRI* corresponds to your typedef.)

Regards,

	Jens
-- 
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

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


#621

FromTim Rentsch <txr@alumni.caltech.edu>
Date2011-07-07 14:13 -0700
Message-ID<kfnzkkpztdh.fsf@x-alumni2.alumni.caltech.edu>
In reply to#616
"Greg A. Woods" <woods@robohack.org> writes:

> James Kuyper <jameskuyper@verizon.net> writes:
>
>> On 07/06/2011 10:58 PM, Greg A. Woods wrote:
>> ...
>> The type of time_t should not matter, since you've casted the value of
>> 't' to int32_t. You should only run into the kind of problem you're
>> referring to if int32_t is long, in which case PRId32 should be 'ld',
>> not 'd'. If it isn't, that's a non-conforming implementation of
>> <stdint.h>, not a defect in the concept of the PRI* macros.
>
> Indeed, that is what one would hope, but in the draft copy of the C99
> standard which I have I cannot find anything which actually says that.

It looks like the actual guarantee is a little bit weaker than
what JK states;  strictly speaking, an implementation still
could be conforming even though it defines PRId32 as 'd'
despite 'int32_t' being the same type as 'long'.  However,
using a PRId32 in a printf() format would still have to work
for an 'int32_t' argument.  As long as the actual execution
behavior matches the execution behavior that would occur if the
"true" conversion specifier were given then the implementation
is in the clear.  Of course, the implementation might choose to
issue a diagnostic, but that is a QOI issue, not a conformance
issue.

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


#675

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 01:04 -0700
Message-ID<ln62nbyj5g.fsf@nuthaus.mib.org>
In reply to#595
"Greg A. Woods" <woods@robohack.org> writes:
[...]
> In order to avoid warnings from some versions of GCC (and perhaps other
> compilers as well -- I haven't had the recent pleasure) on some types of
> systems you will still have to cast some variables declared using
> standard typedef names, such as time_t, to the appropriate int*_t type,
> even when using an appropriate sized PRI* macro with printf(), eg.g. as
> in:
>
> 	typedef time_t long;
>
> 	time_t t = 0;
>
> 	printf("%" PRId32 "\n", (int32_t) t);

Why would you cast a time_t value to int32_t?  Can you show a single
example of someone (other than you) doing so?

[...]
> On other systems PRId32 will be "ld" (sadly even on some 32-bit systems
> with 32-bit int and long!), and if "int32_t" isn't also known as "long"
> down under then you're still screwed.

(I've asked you elsewhere to support this claim.)

[...]

> I've also seen it suggested that _every_ non-base-integer type _always_
> be cast to [u]intmax_t and printed using PRI[ud]MAX:
>
> 	printf("%" PRIuMAX, (uintmax_t) uival);
> 	printf("%" PRIdMAX, (intmax_t) t); /* for signed values */
>
> Now we're safe for every possible underlying type of any typedef name,
> home baked, or standardised.
>
> However if you're always going to do that, then it's far simpler to
> avoid the possibly confusing and unnecessarily verbose (and potentially
> incorrectly defined) use of PRI*MAX and just use "%jd" or "%ju" as
> necessary.  The only advantage of PRI*MAX is that it'll make your code
> more easily ported to non-conforming environments (i.e. those without
> "%jd" et al, and even if PRI*MAX are defined wrong you can still fix it
> with #undef).

I agree that using "%jd" or "%ju" is cleaner than using the PRI* macros.
I certainly don't always think that terseness is a virtue, but in this
case I do prfer the terse version to the more verbose version.

But the argument about non-conforming environments is, frankly, just
silly.  There are pre-C99 implementations that don't support "%jd", and
pre-C99 implementations that don't support the PRI* macros.  I seriously
doubt that there are any real implementations that provide the PRI*MAX
macros but define them incorrectly.  (And again, if you claim that there
are, please provide a specific example.)

> FYI:  The theory here is that the potentially additional heavy lifting
> by printf() is trivial compared to the programmer overhead of trying to
> find and/or define, and/or use, the right PRI* macros.
>
>
> 	A Better Improvement(?):
>
> Too bad printf(3) et al don't have format flag akin to '*' which allows
> you to pass the sizeof() and the signedness of an integer type to it so
> that you don't have to hard-code the integer size in the format
> string....
>
> 	int128_t foo = -1;
> 	uint64_t ubar = 1;
>
> 	#define issigned(v)	(((typeof(v)) -1 < 0) ? true : false)
> 	#define INTPARAM(v)	(int) issigned(v), (int) sizeof(v), v
>
> 	printf("%Si %Si\n", INTPARAM(foo), INTPARAM(ubar));
>
> (I chose "%i" to suggest somewhat that it's different from "%d" or "%u",
> i.e. in that it takes the signedness from the 'S' flag (since I don't
> see %i used very often in the code I read -- it's definitely the new kid
> on the block, and perhaps it can grow up more with a new meaning), but
> of course it need not be -- "%d" and "%u" can also take the sign flag
> using the 'S' flag, but that may confuse the novices more often than not.)
>
> (also, issigned should become a new keyword, as should typeof from GCC,
> though with the former, the latter isn't needed here :-))
>
>
> Does anyone else think this would be worthwhile?  Better ideas anyone?

Let's assume that, for a given implementation, sizeof (int) and sizeof
(long) are both 4.  Your proposal assumes that both these calls:

    int i;
    long l;

    printf("%Si\n", 1, 4, i);
    printf("%Si\n", 1, 4, l);

must work correctly.  The standard doesn't currently guarantee
that int and long are passed the same way as arguments, even if
they happen to be the same size.

I think there have been compilers where int and long are the same
size, but int has more padding bits and a narrower range.

Currently, printf formats are specific to the *type* of the argument,
not to its size.  Your proposal would probably work for almost all
existing implementations, but it would require the standard to impose
requirements on implementations that it currently doesn't impose.

I suspect that the effort of making the necessary changes to the
language standard would exceed the benefit of your proposal --
especially given that converting to intmax_t and using "%jd", or
converting to uintmax_t and using "%ju", solves the problem with
no language or library changes.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#699

From"Greg A. Woods" <woods@robohack.org>
Date2011-07-09 17:23 -0700
Message-ID<874o2vc7ab.fsf@once.weird.com>
In reply to#675
Keith Thompson <kst-u@mib.org> writes:
> 
> "Greg A. Woods" <woods@robohack.org> writes:
> > 
> > 	A Better Improvement(?):
> >
> > Too bad printf(3) et al don't have format flag akin to '*' which allows
> > you to pass the sizeof() and the signedness of an integer type to it so
> > that you don't have to hard-code the integer size in the format
> > string....
> >
> > 	int128_t foo = -1;
> > 	uint64_t ubar = 1;
> >
> > 	#define issigned(v)	(((typeof(v)) -1 < 0) ? true : false)
> > 	#define INTPARAM(v)	(int) issigned(v), (int) sizeof(v), v
> >
> > 	printf("%Si %Si\n", INTPARAM(foo), INTPARAM(ubar));
> >
> > (I chose "%i" to suggest somewhat that it's different from "%d" or "%u",
> > i.e. in that it takes the signedness from the 'S' flag (since I don't
> > see %i used very often in the code I read -- it's definitely the new kid
> > on the block, and perhaps it can grow up more with a new meaning), but
> > of course it need not be -- "%d" and "%u" can also take the sign flag
> > using the 'S' flag, but that may confuse the novices more often than not.)
> >
> > (also, issigned should become a new keyword, as should typeof from GCC,
> > though with the former, the latter isn't needed here :-))
> >
> >
> > Does anyone else think this would be worthwhile?  Better ideas anyone?
>
> Let's assume that, for a given implementation, sizeof (int) and sizeof
> (long) are both 4.  Your proposal assumes that both these calls:
>
>     int i;
>     long l;
>
>     printf("%Si\n", 1, 4, i);
>     printf("%Si\n", 1, 4, l);
>
> must work correctly.  The standard doesn't currently guarantee
> that int and long are passed the same way as arguments, even if
> they happen to be the same size.
>
> I think there have been compilers where int and long are the same
> size, but int has more padding bits and a narrower range.

Does that matter in practice?  Do we have to assume the padding bits are
zeros for it to work?  Finding the sign bit is of course the trick, but
are you sure sizeof() reports the padding as well?  I'm not.

In an LP64I32 environment I would expect the CPP result to be as follows
even if the implementation always stores 64-bit words on the stack:

	printf("%Si\n", 1, 8, i);
	printf("%Si\n", 1, 4, l);

In that case the implementation of printf() would of course already have
to be aware of this issue and it would be trivial for "%Si" to deal with
it.

> I suspect that the effort of making the necessary changes to the
> language standard would exceed the benefit of your proposal --
> especially given that converting to intmax_t and using "%jd", or
> converting to uintmax_t and using "%ju", solves the problem with
> no language or library changes.

Indeed I'm not convinced either that my proposal is much more elegant
than just always using a cast to [u]intmax_t.

Except for the sign handling -- I hate having to find and fix every use
of a variable as a varargs parameter after I change it's signedness, and
I can't count the number of times I've found places where others have
failed to be so careful, or indeed where I have failed to be so careful
in the past.

In fact initially when I was thinking this up I was only thinking of the
sign issue, then I ran across yet another question on a mailing list
about what to do to handle the time_t problem yet again.  (You see,
printing time_t raw values is often VERY common in some circles, indeed
important for data and protocol purposes, not just debugging!)  (I've
also been wanting to add "%m" (ala syslog(3) to my libc for at least a
decade now too.)

I would probably want to have INTPARAM() actually be named something
more like i_() to make it less abrasive and intrusive.  :-)

-- 
						Greg A. Woods
						RoboHack

<woods@robohack.ca>     living on the edge      http://www.robohack.ca/

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


#703

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 19:03 -0700
Message-ID<lnhb6ux57t.fsf@nuthaus.mib.org>
In reply to#699
"Greg A. Woods" <woods@robohack.org> writes:
> Keith Thompson <kst-u@mib.org> writes:
[...]
>> Let's assume that, for a given implementation, sizeof (int) and sizeof
>> (long) are both 4.  Your proposal assumes that both these calls:
>>
>>     int i;
>>     long l;
>>
>>     printf("%Si\n", 1, 4, i);
>>     printf("%Si\n", 1, 4, l);
>>
>> must work correctly.  The standard doesn't currently guarantee
>> that int and long are passed the same way as arguments, even if
>> they happen to be the same size.
>>
>> I think there have been compilers where int and long are the same
>> size, but int has more padding bits and a narrower range.
>
> Does that matter in practice?  Do we have to assume the padding bits are
> zeros for it to work?  Finding the sign bit is of course the trick, but
> are you sure sizeof() reports the padding as well?  I'm not.

Yes, the value yielded by sizeof includes any padding bits.

> In an LP64I32 environment I would expect the CPP result to be as follows
> even if the implementation always stores 64-bit words on the stack:
>
> 	printf("%Si\n", 1, 8, i);
> 	printf("%Si\n", 1, 4, l);
>
> In that case the implementation of printf() would of course already have
> to be aware of this issue and it would be trivial for "%Si" to deal with
> it.

Sure, there's no problem *in an LP64I32 environment*.  That's not
the environment I was talking about.  I'm talking about a (perhaps
hypothetical) environment where int and long are the same size but
nevertheless have different characteristics.  Does printf need to
know the difference?  It depends on just how they differ.  The C
standard allows for a lot of variation.

Maybe your proposal would actually work on every environment
that exists in the real world.  But for it to be adopted, the
standard would have to make sigificant changes to the requirements
it imposes on implementations for the behavior of integer types,
which implies a great deal of work to update the standard with the
revised assumptions.  (Which could, some day, prevent a conforming
C implementation for some future system.)

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#713

FromMarcin Grzegorczyk <mgrzegor@poczta.onet.pl>
Date2011-07-11 20:40 +0200
Message-ID<ivfg2r$ej7$1@dont-email.me>
In reply to#703
Keith Thompson wrote:
> "Greg A. Woods"<woods@robohack.org>  writes:
>> Keith Thompson<kst-u@mib.org>  writes:
> [...]
>>> Let's assume that, for a given implementation, sizeof (int) and sizeof
>>> (long) are both 4.  Your proposal assumes that both these calls:
>>>
>>>      int i;
>>>      long l;
>>>
>>>      printf("%Si\n", 1, 4, i);
>>>      printf("%Si\n", 1, 4, l);
>>>
>>> must work correctly.  The standard doesn't currently guarantee
>>> that int and long are passed the same way as arguments, even if
>>> they happen to be the same size.
>>>
>>> I think there have been compilers where int and long are the same
>>> size, but int has more padding bits and a narrower range.
>>
>> Does that matter in practice?  Do we have to assume the padding bits are
>> zeros for it to work?  Finding the sign bit is of course the trick, but
>> are you sure sizeof() reports the padding as well?  I'm not.
>
> Yes, the value yielded by sizeof includes any padding bits.
>
>> In an LP64I32 environment I would expect the CPP result to be as follows
>> even if the implementation always stores 64-bit words on the stack:
>>
>> 	printf("%Si\n", 1, 8, i);
>> 	printf("%Si\n", 1, 4, l);
>>
>> In that case the implementation of printf() would of course already have
>> to be aware of this issue and it would be trivial for "%Si" to deal with
>> it.
>
> Sure, there's no problem *in an LP64I32 environment*.  That's not
> the environment I was talking about.  I'm talking about a (perhaps
> hypothetical) environment where int and long are the same size but
> nevertheless have different characteristics.  Does printf need to
> know the difference?  It depends on just how they differ.  The C
> standard allows for a lot of variation.
>
> Maybe your proposal would actually work on every environment
> that exists in the real world.  But for it to be adopted, the
> standard would have to make sigificant changes to the requirements
> it imposes on implementations for the behavior of integer types,
> which implies a great deal of work to update the standard with the
> revised assumptions.

That's why I'd rather propose, instead of size, an enumeration with 
distinct (implementation-defined) values for each valid type supported 
by the implementation.  A standardized macro could then map expression 
type to an enumeration constant via the C1X generic selection construct 
(i.e. no compiler magic needed); as an added benefit, the macro would 
catch cases when a completely wrong type, like a floating-point or 
structure type, is passed to a specifier that expects only integer types.

Not that I really believe such a proposal would have any chance of being 
accepted by WG14 at the current state of things - there's no existing 
practice.
-- 
Marcin Grzegorczyk

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


#714

FromKeith Thompson <kst-u@mib.org>
Date2011-07-11 11:56 -0700
Message-ID<lnpqlgve7z.fsf@nuthaus.mib.org>
In reply to#713
Marcin Grzegorczyk <mgrzegor@poczta.onet.pl> writes:
> Keith Thompson wrote:
[snip]
>> Sure, there's no problem *in an LP64I32 environment*.  That's not
>> the environment I was talking about.  I'm talking about a (perhaps
>> hypothetical) environment where int and long are the same size but
>> nevertheless have different characteristics.  Does printf need to
>> know the difference?  It depends on just how they differ.  The C
>> standard allows for a lot of variation.
>>
>> Maybe your proposal would actually work on every environment
>> that exists in the real world.  But for it to be adopted, the
>> standard would have to make sigificant changes to the requirements
>> it imposes on implementations for the behavior of integer types,
>> which implies a great deal of work to update the standard with the
>> revised assumptions.
>
> That's why I'd rather propose, instead of size, an enumeration with 
> distinct (implementation-defined) values for each valid type supported 
> by the implementation.  A standardized macro could then map expression 
> type to an enumeration constant via the C1X generic selection construct 
> (i.e. no compiler magic needed); as an added benefit, the macro would 
> catch cases when a completely wrong type, like a floating-point or 
> structure type, is passed to a specifier that expects only integer types.

But that wouldn't handle user-defined integer types, something that
Greg's original proposal was *intended* to do.

I'm not sure I see the benefit of the enumeration.  It seems like
just another set of semi-arbitrary names associated with each
integer type.  For predefined types, we already have the *_MIN
and *_MAX macros and the various printf strings ("d" for int, "ld"
for long int, and so forth).  For the types defined in <stdint.h>,
we have the PRI* and SCN* macros.  For all of these, some attempt
has been made to make the names or strings have some meaningful
relationship to the types, but it's not at all straightforward;
we have SHRT_MAX rather than SHORT_MAX, and LLONG_MAX rather than
LONG_LONG_MAX, for example.

I don't think a universal solution is likely to happen (especially
since we don't have the option of dropping the existing mess) --
but if I were designing C from scratch, I'd want to have a mechanism
for determining all these things from the type name itself (and it
could also be applied to an expression of the type).

Ada, for example, has something called "attributes", whose syntax
is a prefix, followed by an apostrophe, followed by a predefined
attribute name.  The maximum values of types Character, Integer, and
Float are Character'Last, Integer'Last, and Float'Last, respectively.

We couldn't use that particular syntax for C, but something that
looks like a macro invocation but is actually handled by the compiler
might do the trick: MAX(int), MAX(long int), etc.  Then PRId(foo)
would expand to the correct printf conversion specifier for any
signed integer type "foo".

> Not that I really believe such a proposal would have any chance of being 
> accepted by WG14 at the current state of things - there's no existing 
> practice.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#716

FromMarcin Grzegorczyk <mgrzegor@poczta.onet.pl>
Date2011-07-11 21:40 +0200
Message-ID<ivfjj2$74j$1@dont-email.me>
In reply to#714
Keith Thompson wrote:
> Marcin Grzegorczyk<mgrzegor@poczta.onet.pl>  writes:
[...]
>> That's why I'd rather propose, instead of size, an enumeration with
>> distinct (implementation-defined) values for each valid type supported
>> by the implementation.  A standardized macro could then map expression
>> type to an enumeration constant via the C1X generic selection construct
>> (i.e. no compiler magic needed); as an added benefit, the macro would
>> catch cases when a completely wrong type, like a floating-point or
>> structure type, is passed to a specifier that expects only integer types.
>
> But that wouldn't handle user-defined integer types, something that
> Greg's original proposal was *intended* to do.

What user-defined types wouldn't it handle?  Typedefs are just aliases 
for existing types.

> I'm not sure I see the benefit of the enumeration.  It seems like
> just another set of semi-arbitrary names associated with each
> integer type.

Yes, hence the standard would not need to list those names, just define 
a macro to map, in an implementation-defined manner, types to values 
expected by *printf().  In fact, you're right that enumeration is not 
necessary; a plain int would suffice.

[...]
> but if I were designing C from scratch, I'd want to have a mechanism
> for determining all these things from the type name itself (and it
> could also be applied to an expression of the type).
>
> Ada, for example, has something called "attributes", whose syntax
> is a prefix, followed by an apostrophe, followed by a predefined
> attribute name.  The maximum values of types Character, Integer, and
> Float are Character'Last, Integer'Last, and Float'Last, respectively.

D has something similar called properties, with a much more C-like syntax:

   int foo;
   long bar;
   /* ... */
   if (bar > foo.max) /* ... */

But then, D actually is intended to be C designed from scratch :-)
-- 
Marcin Grzegorczyk

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


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

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


csiph-web