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 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#650

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-07-08 07:41 -0400
Message-ID<iv6qdm$ei8$1@dont-email.me>
In reply to#638
On 07/07/2011 11:58 PM, Greg A. Woods wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>>
>> The right way to warn about mismatches: only warn when there's an actual
>> mismatch.
> 
> It is an "actual" mis-match -- at least if you intend your code to be
> portable.

For every conforming implementation of C, PRI32d must be a correct match
to whichever type int32_t represents in that implementation. While
implementations are permitted to issue diagnostics for any reason they
like ("warning: identifiers containing 'z' make me feel fuzzy!"), an
implementation which diagnoses the correct match that PRI32d must have
with int32_t has low QoI because it's wasting the developer's time.

>> The right way to #define PRI32d: #define it to be a format specification
>> which is NOT a mismatch for the corresponding promoted type; no cast
>> required.
> 
> Someone should try this on some GNU/Linux variants for me -- I think
> from my manual inspection of glibc header sources online that you'll get
> a warning (if you turn on the right warning flags)....
> It works OK on NetBSD and on OS X.

If it doesn't work on a particular implementation, then that
implementation is non-conforming. If the vendor cares about conformance
(not all do), then a complaint about that fact to the vendor should be
well-received.

>> The right way to use PRI32d (no cast required):
>> 	int32_t value;
>> 	// set value
>> 	printf("value:%" PRI32d "\n", value);
> 
> Some code does that, but most folks don't seem to be PL/1-heads,
> i.e. that pedantic about how many bits they want.  Most folks want an
> "int", or maybe a "long" for bigger values.  They can't be bothered to
> worry about numbers of bits.

Then why are they using int32_t? They only need the PRI* macros if they
choose to use the new size-named types. If all they want is long, they
should use it, and use the corresponding format specification. int32_t
is only appropriate for precisely and portably meeting interface
specifications; for most other purposes, int_fast32_t is more
appropriate. For most of those same purposes 'long' is probably just as
good, and easier to type.

>>>>> Also, I repeat, C99 strftime() is unable to print the value of a time_t
>>>>> as an integer representation of seconds since the epoch of time_t. ...
>>
>> Well, of course not. For that you use
>> 	printf("seconds since epoch:%.0f\n", difftime(value,epoch));
> 
> Decades of unix tradition flushed down the drain by C99.  :-)

What tradition are you talking about?

What you've specified is not something I can see any point in printing
out, but if I did want to print it out, that code is what I'd use to
print it, whether in C90 or C99, and for exactly the same reasons with
either standard. It's not Unix-specific, but then I normally try to
avoid writing OS-specific code.

If you're willing to restrict the portability of your code to Unix and
Unix-like systems (which is not a major restriction), I agree that there
are simpler ways to write it, but those ways also didn't change between
C90 and C99. So what is it you're complaining about?
-- 
James Kuyper

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


#669

From"Greg A. Woods" <woods@robohack.org>
Date2011-07-08 23:05 -0700
Message-ID<878vs8dm52.fsf@once.weird.com>
In reply to#650
James Kuyper <jameskuyper@verizon.net> writes:
>
> On 07/07/2011 11:58 PM, Greg A. Woods wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
>>>
>>> The right way to warn about mismatches: only warn when there's an actual
>>> mismatch.
>> 
>> It is an "actual" mis-match -- at least if you intend your code to be
>> portable.
>
> For every conforming implementation of C, PRI32d must be a correct match
> to whichever type int32_t represents in that implementation. While
> implementations are permitted to issue diagnostics for any reason they
> like ("warning: identifiers containing 'z' make me feel fuzzy!"), an
> implementation which diagnoses the correct match that PRI32d must have
> with int32_t has low QoI because it's wasting the developer's time.

I'm explicitly not talking about the ideal world where every
implementation is conforming!

This is an issue of application in the real-world, of helping to make
real-world code work in real-world environments.


> Then why are they using int32_t? They only need the PRI* macros if they
> choose to use the new size-named types.

Because people love to use new features, but when those features are not
really well documented, and when they can easily lead to such problems,
those features might cause more harm than good.  Read some real code
(e.g. do some internet searches on *PRI* and *FMT* to find examples) and
see for yourself.


>>> Well, of course not. For that you use
>>> 	printf("seconds since epoch:%.0f\n", difftime(value,epoch));
>> 
>> Decades of unix tradition flushed down the drain by C99.  :-)
>
> What tradition are you talking about?

The tradition of course that time_t is, always has been, and always will
be, an _integer_ number of seconds since the epoch.

> What you've specified is not something I can see any point in printing
> out,

Assumptions, assumptions, assumptions!  You know what they say about
assumptions!  :-)

-- 
						Greg A. Woods
						RoboHack

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

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


#674

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 00:50 -0700
Message-ID<lnaacnyjt2.fsf@nuthaus.mib.org>
In reply to#669
"Greg A. Woods" <woods@robohack.org> writes:
> James Kuyper <jameskuyper@verizon.net> writes:
>> On 07/07/2011 11:58 PM, Greg A. Woods wrote:
>>> James Kuyper <jameskuyper@verizon.net> writes:
[...]
>>>> Well, of course not. For that you use
>>>> 	printf("seconds since epoch:%.0f\n", difftime(value,epoch));
>>> 
>>> Decades of unix tradition flushed down the drain by C99.  :-)

No, difftime() was introduced by C90.

>> What tradition are you talking about?
>
> The tradition of course that time_t is, always has been, and always will
> be, an _integer_ number of seconds since the epoch.

In this very thread, Lawrence Jones wrote:
| I know of at least one implementation that used double, although it
| only stored integer values in it (double had more precision than
| long).

>> What you've specified is not something I can see any point in printing
>> out,
>
> Assumptions, assumptions, assumptions!  You know what they say about
> assumptions!  :-)

Yes, they make an ass out of you and umption.

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


#677 — Re: [incorrectly implementd] PRI* considered harmful

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-07-09 06:38 -0400
SubjectRe: [incorrectly implementd] PRI* considered harmful
Message-ID<iv9b34$uvi$1@dont-email.me>
In reply to#669
On 07/09/2011 02:05 AM, Greg A. Woods wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>>
>> On 07/07/2011 11:58 PM, Greg A. Woods wrote:
>>> James Kuyper <jameskuyper@verizon.net> writes:
>>>>
>>>> The right way to warn about mismatches: only warn when there's an actual
>>>> mismatch.
>>>
>>> It is an "actual" mis-match -- at least if you intend your code to be
>>> portable.
>>
>> For every conforming implementation of C, PRI32d must be a correct match
>> to whichever type int32_t represents in that implementation. While
>> implementations are permitted to issue diagnostics for any reason they
>> like ("warning: identifiers containing 'z' make me feel fuzzy!"), an
>> implementation which diagnoses the correct match that PRI32d must have
>> with int32_t has low QoI because it's wasting the developer's time.
> 
> I'm explicitly not talking about the ideal world where every
> implementation is conforming!

The title of your thread was "PRI* considered harmful"; this title
apparently incorrectly reflects your concerns, I've corrected it in this
message.

"Incorrectly implemented" anything is (almost always, but I'm sure there
are exceptions) a problem, but it's not a problem with the feature being
incorrectly implemented, it's a problem with the incorrect
implementation. Incorrectly implemented "%ld" formats would also be a
problem; but not a problem with the standard that specifies what correct
implementation of those formats means.

The problem you're running into is PRECISELY the problem that the PRI*
macros were designed to solve. They are correctly designed to solve it
(though excessively clumsy, in my opinion). The standard's specification
mandates that they solve it. Defining them in such a way as to actually
solve the problem is trivial; it requires true idiocy to implement them
incorrectly (though I would not recommend saying so to the person that
you ask to fix the problem). Any failure of those macros to be correctly
defined can be easily corrected by any implementor that actually cares
enough to bother doing so. If you've actually reported such
non-conformance to an implementor, and had your complaint ignored, that
would be worth complaining about (though your complaint should be lodged
in a forum specific to that implementation, not here).

But there's no point in complaining about a feature of the standard on
the basis of the behavior of a system that fails to conform to the
specifications of the standard for that feature.

...
>> Then why are they using int32_t? They only need the PRI* macros if they
>> choose to use the new size-named types.
> 
> Because people love to use new features, but when those features are not
> really well documented, and when they can easily lead to such problems,
> those features might cause more harm than good.  Read some real code
> (e.g. do some internet searches on *PRI* and *FMT* to find examples) and
> see for yourself.

People misuse "long int", too. That doesn't mean that "long int" has
something wrong with it.

>>>> Well, of course not. For that you use
>>>> 	printf("seconds since epoch:%.0f\n", difftime(value,epoch));
>>>
>>> Decades of unix tradition flushed down the drain by C99.  :-)
>>
>> What tradition are you talking about?
> 
> The tradition of course that time_t is, always has been, and always will
> be, an _integer_ number of seconds since the epoch.

And what has C99 done to flush that down the drain? Code which makes
that assumption is precisely as non-portable in C99 as it was in C90,
but on the implementations where it's non-portable assumptions are
correct, it will work just as well in C99 as in C90. In point of fact,
C99's new [u]intmax_t and the corresponding new printf() format
specifiers make it possible to write code embodying that unportable
assumption in as widely portable a fashion as possible.

>> What you've specified is not something I can see any point in printing
>> out,
> 
> Assumptions, assumptions, assumptions!  You know what they say about
> assumptions!  :-)

Yes, I know - and it's complete nonsense. It's impossible to think
without making assumptions; the best you can do is to be aware of which
assumptions you make, to avoid making unnecessary assumptions, and to
make sure that when it is necessary to make assumptions (as is
inevitably the case), that they are as well justified as possible.

All of which is completely irrelevant to what I said; I made no
assumptions, I just don't know of a good reason for printing them out,
except for debugging purposes, and most debuggers I'm familiar with
don't require you to provide printf() formats. I use debugging printf()s
all the time, but it's not exactly difficult to get this one right;
you're just making it difficult by insisting on approaching the problem
incorrectly, and then complaining about the fact that it's not the right
approach.
-- 
James Kuyper

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


#686

FromHans-Bernhard Bröker <HBBroeker@t-online.de>
Date2011-07-09 21:07 +0200
Message-ID<97rn72FfmpU1@mid.dfncis.de>
In reply to#669
On 09.07.2011 08:05, Greg A. Woods wrote:
> I'm explicitly not talking about the ideal world where every
> implementation is conforming!

Then with all due respect, you're barking up the wrong tree.

Implementation errors are not the standard's fault unless you can prove 
that the standard specified the feature in question in such a way that 
said feature could not be implemented correctly.  Good luck with tyring 
that.

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


#663

FromKeith Thompson <kst-u@mib.org>
Date2011-07-08 09:52 -0700
Message-ID<ln4o2wzpcn.fsf@nuthaus.mib.org>
In reply to#638
"Greg A. Woods" <woods@robohack.org> writes:
> James Kuyper <jameskuyper@verizon.net> writes:
[...]
>>>>> Also, I repeat, C99 strftime() is unable to print the value of a time_t
>>>>> as an integer representation of seconds since the epoch of time_t. ...
>>
>> Well, of course not. For that you use
>> 	printf("seconds since epoch:%.0f\n", difftime(value,epoch));
>
> Decades of unix tradition flushed down the drain by C99.  :-)

There were no relevant changes in <time.h> between C90 and C99.
Neither C90 nor C99 guarantees anything about the representation of
time_t, except that it's a arithmetic type capable of representing
times.  You're free to assume more than that if you don't mind going
beyond what the language standard promises.

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


#649

FromRichard Kettlewell <rjk@greenend.org.uk>
Date2011-07-08 11:45 +0100
Message-ID<87hb6xgie8.fsf@araminta.anjou.terraraq.org.uk>
In reply to#633
"Greg A. Woods" <woods@robohack.org> writes:
> Keith Thompson <kst-u@mib.org> writes:

>> I suggest that, at least in this specific case, you're looking for
>> problems that are unlikely to exist in any real implementation.
>
> You mean like in some versions GNU/Linux, or more specifically, I think,
> some(all?) versions of glibc where PRId32 is "%ld" even on 32-bit
> systems with 32-bit ints and where int32_t is a "signed int"?  At least
> as far as I can tell. (I don't generally use GNU/Linux, and I despise
> glibc for many other reasons than this :-))

Glibc on 32-bit Linux has int32_t = signed int and PRId32 = %d.

>> If you're printing ints and longs, you don't need to use the PRI*
>> macros.  Just use "%d" and "%ld", respectively.  Or did I misunderstand
>> your point?
>
> That is sort of my point.  The tricky part comes when one wants to print
> something like time_t (e.g. knowing that it is an integer in 99.999% of
> host environments where one's code can ever be used), then one still has
> to decide whether to use "%ld" and cast to a "long", or to use "%lld"
> and cast to "long long", or to just give up on performance and always
> use "%jd" and cast to "intmax_t".
>
> PRI* are in fact being misused in real-world code, and to the best of my
> understanding most people cannot make valid use of them -- i.e. they are
> harmful to the goal of making code more portable.  It's hard enough
> getting junoir programmers to use casts properly in C, and they still
> trip up some of us after dozens of years of using them.

Of course they can be used properly.  If what you have is an int32_t,
use PRId32.  If you have an int, use %d.

-- 
http://www.greenend.org.uk/rjk/

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


#670

From"Greg A. Woods" <woods@robohack.org>
Date2011-07-08 23:14 -0700
Message-ID<87vcvcc75o.fsf@once.weird.com>
In reply to#649
Richard Kettlewell <rjk@greenend.org.uk> writes:

> "Greg A. Woods" <woods@robohack.org> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>
>>> I suggest that, at least in this specific case, you're looking for
>>> problems that are unlikely to exist in any real implementation.
>>
>> You mean like in some versions GNU/Linux, or more specifically, I think,
>> some(all?) versions of glibc where PRId32 is "%ld" even on 32-bit
>> systems with 32-bit ints and where int32_t is a "signed int"?  At least
>> as far as I can tell. (I don't generally use GNU/Linux, and I despise
>> glibc for many other reasons than this :-))
>
> Glibc on 32-bit Linux has int32_t = signed int and PRId32 = %d.

I've seen dozens of examples in internet searches where PRId32 is "ld"
on many kinds of GNU/Linux distributions.

Even the manual page prid32(3) says so in representative examples that
I've bothered to look at.  (google's "lucky one" at the moment is this
one <URL:http://linux.die.net/man/3/prid32>)

Where did you find it to be just "d"?  (I'm asuming you mean just "d",
not really "%d" :-))


I couldn't quite work out whether int32_t was usually "signed int" or
not though without getting a login on a representative machine to
compile some test code on, but that's what I was assuming.

-- 
						Greg A. Woods
						RoboHack

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

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


#673

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 00:47 -0700
Message-ID<lnei1zyjyc.fsf@nuthaus.mib.org>
In reply to#670
"Greg A. Woods" <woods@robohack.org> writes:
[...]
> I couldn't quite work out whether int32_t was usually "signed int" or
> not though without getting a login on a representative machine to
> compile some test code on, but that's what I was assuming.

I believe you'll find your assumption is wrong.

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


#676

FromRichard Kettlewell <rjk@greenend.org.uk>
Date2011-07-09 10:51 +0100
Message-ID<87r55zlr3j.fsf@araminta.anjou.terraraq.org.uk>
In reply to#670
"Greg A. Woods" <woods@robohack.org> writes:
> Richard Kettlewell <rjk@greenend.org.uk> writes:
>> "Greg A. Woods" <woods@robohack.org> writes:

>>> You mean like in some versions GNU/Linux, or more specifically, I think,
>>> some(all?) versions of glibc where PRId32 is "%ld" even on 32-bit
>>> systems with 32-bit ints and where int32_t is a "signed int"?  At least
>>> as far as I can tell. (I don't generally use GNU/Linux, and I despise
>>> glibc for many other reasons than this :-))
>>
>> Glibc on 32-bit Linux has int32_t = signed int and PRId32 = %d.
>
> I've seen dozens of examples in internet searches where PRId32 is "ld"
> on many kinds of GNU/Linux distributions.

For instance?

> Even the manual page prid32(3) says so in representative examples that
> I've bothered to look at.  (google's "lucky one" at the moment is this
> one <URL:http://linux.die.net/man/3/prid32>)

I don't know where die.net got that man page from (it doesn't exist even
on my 'freshest' Linux system) but it doesn't correspond with the actual
implementation as found here.

> Where did you find it to be just "d"?  (I'm asuming you mean just "d",
> not really "%d" :-))

By executing printf("%s", PRId32) in a small test program.

I didn't check every possible Linux distribution, but it sounds like
you've done the experiment on precisely zero of them.

-- 
http://www.greenend.org.uk/rjk/

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


#678

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-07-09 06:43 -0400
Message-ID<iv9bcp$rn$1@dont-email.me>
In reply to#670
On 07/09/2011 02:14 AM, Greg A. Woods wrote:
> Richard Kettlewell <rjk@greenend.org.uk> writes:
> 
>> "Greg A. Woods" <woods@robohack.org> writes:
>>> Keith Thompson <kst-u@mib.org> writes:
>>
>>>> I suggest that, at least in this specific case, you're looking for
>>>> problems that are unlikely to exist in any real implementation.
>>>
>>> You mean like in some versions GNU/Linux, or more specifically, I think,
>>> some(all?) versions of glibc where PRId32 is "%ld" even on 32-bit
>>> systems with 32-bit ints and where int32_t is a "signed int"?  At least
>>> as far as I can tell. (I don't generally use GNU/Linux, and I despise
>>> glibc for many other reasons than this :-))
>>
>> Glibc on 32-bit Linux has int32_t = signed int and PRId32 = %d.
> 
> I've seen dozens of examples in internet searches where PRId32 is "ld"
> on many kinds of GNU/Linux distributions.

And have you verified that, on those particular distributions, uint32_t
is NOT long int?

...
> I couldn't quite work out whether int32_t was usually "signed int" or
> not though without getting a login on a representative machine to
> compile some test code on, but that's what I was assuming.

Well, what did you just say about assumptions? This is a particularly
egregious example. You just assumed that "ld" is an incorrect value for
PRI32d, because you just assumed that int32_t is 'signed int'? Please
don't bother complaining about non-conforming implementations until
you've at least verified that they do, in fact, fail to conform.
-- 
James Kuyper

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


#662

FromKeith Thompson <kst-u@mib.org>
Date2011-07-08 09:49 -0700
Message-ID<ln8vs8zpj6.fsf@nuthaus.mib.org>
In reply to#633
"Greg A. Woods" <woods@robohack.org> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Presumably an implementation that warns about mismatched printf
>> formats, even those that happen to work (say, because int and long
>> are the same size) would define the PRI* macros so they avoid those
>> warnings when used correctly.
>
> "when used correctly"?  Just how is one to do that?  Without always
> using a cast, that is?

If you want to print a value of a type defined in <stdint.h>,
use the macro that corresponds to that type.

If you want to print a value of some other integer type, you'll
need to use some other solution.  The PRI* macros will probably
not be part of that solution.  Yes, a cast might be necessary;
that's not such a bad thing.

You seem to be criticizing the PRI* macros because they're not
a universal solution to the problem of printing integer values.
They were never intended to be.  They're intended only for the
types defined in <stdint.h>.

> BTW, if one does always use a cast, then one can always use the exact
> right cast for "%d" or "%ld" or "%u" or "%lu", etc., and thus the PRI*
> macros once again prove useless and futile.

So don't use them.

>> I suggest that, at least in this specific case, you're looking for
>> problems that are unlikely to exist in any real implementation.
>
> You mean like in some versions GNU/Linux, or more specifically, I think,
> some(all?) versions of glibc where PRId32 is "%ld" even on 32-bit
> systems with 32-bit ints and where int32_t is a "signed int"?  At least
> as far as I can tell. (I don't generally use GNU/Linux, and I despise
> glibc for many other reasons than this :-))

On my system (Ubuntu 11.04, gcc 4.5.2, glibc 2.13), int32_t is a
typedef for int, and PRId32 is defined as "d".

Can you cite a specific real-world system where the definitions of
int32_t and PRId32 are inconsistent?  Can you demonstrate that this
program:

#include <stdio.h>
#include <inttypes.h>
int main(void)
{
    int32_t x = 42;
    printf("x = %" PRId32 "\n", x);
    return 0;
}

triggers a warning about the format string?  If it's a big a problem
as you say it is, that shouldn't be difficult.

>> If you're printing ints and longs, you don't need to use the PRI*
>> macros.  Just use "%d" and "%ld", respectively.  Or did I misunderstand
>> your point?
>
> That is sort of my point.  The tricky part comes when one wants to print
> something like time_t (e.g. knowing that it is an integer in 99.999% of
> host environments where one's code can ever be used), then one still has
> to decide whether to use "%ld" and cast to a "long", or to use "%lld"
> and cast to "long long", or to just give up on performance and always
> use "%jd" and cast to "intmax_t".

The PRI* macros are not intended to solve the problem of printing
time_t values.  They're intended for printing values of the types
defined in <stdint.h>.

You seem to have a firm grasp on the options for printing raw
time_t values.  (Though I suggest that converting to intmax_t isn't
likely to be a significant performance issue.  Your program will
probably spend a lot more time just sending the characters to their
destination than it spends formatting them.)

> PRI* are in fact being misused in real-world code, and to the best of my
> understanding most people cannot make valid use of them -- i.e. they are
> harmful to the goal of making code more portable.  It's hard enough
> getting junoir programmers to use casts properly in C, and they still
> trip up some of us after dozens of years of using them.

I don't doubt that some programmers sometimes misuse the PRI* macros.
There probably isn't a feature of any language that isn't misused
sometimes.  Can you provide specific examples of this misuse?  And if
so, can you demonstrate that this misuse is the fault of the feature
itself, and not of the programmers who misuse it?

> Thus my suggestion of enhancing printf() instead of trying to suggest
> that the standard provide more PRI* like macros.  Let's get rid of the
> problem entirely, or at least provide a truely safe and innovative
> solution for those who would prefer a better way.

You know what?  I might actually agree with whatever point you're
trying to make, if I can figure out just what it is.  I've never
found any use for the PRI* macros myself.  But your underlying point
is obscured by your claims about problems with the PRI* macros that,
as far as I can tell, do not actually exist.

[...]

>>> Also, I repeat, C99 strftime() is unable to print the value of a time_t
>>> as an integer representation of seconds since the epoch of time_t.  (C99
>>> does not have the '%s' specifier that many implementations do have.)
>>
>> That's because the language doesn't say that time_t represents an
>> integer number of seconds since some epoch.  It says only that it's
>> an arithmetic type "capable of representing times".  Among many
>> other possibilities, it could use the value 20110707233829, or
>> 0x20110707233829, or 020110707233829, to represent the current time.
>> Or the resolution could be larger or smaller than one second.
>> The relationship between time_t values and real times needn't even
>> be linear.
>
> I think you missed my point, _entirely_.  C99 strftime() cannot EVER do
> what I want, no matter how time_t is defined.  I.e. strftime() IS NOT
> the answer -- not even close, not even for just time_t.  Get off your
> high horse about time_t!  :-)   It's an example, not the whole problem.

I didn't say that strftime() is the answer to *your* problem.  It is the
answer to the problem of printing meaningful representations of time_t
values *unless* you need, for some reason, to print the raw value.
>
>> No, the PRI* macros do not solve the problem of printing raw time_t
>> values; they're not intended to.  I do sometimes print such values
>> myself; I generally just write something like
>>
>>     printf("%ld\n", (long)time(NULL));
>>
>> which isn't entirely portable, but it's good enough for most purposes.
>
> Every bit of code like that will break on POSIX systems in 2038.  :-)
> Even on the systems which update time_t to be more than 32 bits.

It won't break if long is 64 bits.

But I write code like the above when the expected useful lifetime
of the program is just a few minutes.  If I needed to print a raw
time_t value in production code, I'd use a more reliable method
(like the one I posted earlier in this thread).

>>>> The only library-defined *integer* type that isn't covered, as far
>>>> as I can tell, is wchar_t.  You wouldn't normally want to print that
>>>> as integer value anyway.
>>>
>>> It's not the only one (not even close).
>>
>> So what are the others?
>
> UTSL!

"Use the source, Luke!", right?

No.  I already checked the standard, and didn't find any examples
other than wchar_t.  It's possible that I missed something, but
since you're the one making the claim, you can support it.

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


#671

From"Greg A. Woods" <woods@robohack.org>
Date2011-07-08 23:24 -0700
Message-ID<87r560c6pp.fsf@once.weird.com>
In reply to#662
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.  :-)


> On my system (Ubuntu 11.04, gcc 4.5.2, glibc 2.13), int32_t is a
> typedef for int, and PRId32 is defined as "d".

good to know


> Can you cite a specific real-world system where the definitions of
> int32_t and PRId32 are inconsistent?  Can you demonstrate that this
> program:
>
> #include <stdio.h>
> #include <inttypes.h>
> int main(void)
> {
>     int32_t x = 42;
>     printf("x = %" PRId32 "\n", x);
>     return 0;
> }
>
> triggers a warning about the format string?  If it's a big a problem
> as you say it is, that shouldn't be difficult.

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


>> Thus my suggestion of enhancing printf() instead of trying to suggest
>> that the standard provide more PRI* like macros.  Let's get rid of the
>> problem entirely, or at least provide a truely safe and innovative
>> solution for those who would prefer a better way.
>
> You know what?  I might actually agree with whatever point you're
> trying to make, if I can figure out just what it is.  I've never
> found any use for the PRI* macros myself.  But your underlying point
> is obscured by your claims about problems with the PRI* macros that,
> as far as I can tell, do not actually exist.

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.

The reason I've harped on PRI* is that their existance would also be
entirerly unnecessary were something like my proposal implemented, and
because there are now countless examples of people trying vainly to
emulate the PRI* macros for their own use, but even more often getting
it entirely wrong.

-- 
						Greg A. Woods
						RoboHack

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

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


#672

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 00:45 -0700
Message-ID<lniprbyk09.fsf@nuthaus.mib.org>
In reply to#671
"Greg A. Woods" <woods@robohack.org> writes:
> 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.  :-)

And yet you've spent most of this thread complaining about the
PRI* macros, even in the subject header of your original message.
Why is that?

The PRI* macros can't be removed from the standard library without
breaking existing code.  Sometimes there are compelling reasons to do
that kind of thing (removing gets(), for example), but there are no
such reasons for the PRI* macros, since they *can* be used correctly.

As I recall, your original article had a proposal for extending printf
format strings.  Perhaps I'll go back and find it.

>> On my system (Ubuntu 11.04, gcc 4.5.2, glibc 2.13), int32_t is a
>> typedef for int, and PRId32 is defined as "d".
>
> good to know
>
>
>> Can you cite a specific real-world system where the definitions of
>> int32_t and PRId32 are inconsistent?  Can you demonstrate that this
>> program:
>>
>> #include <stdio.h>
>> #include <inttypes.h>
>> int main(void)
>> {
>>     int32_t x = 42;
>>     printf("x = %" PRId32 "\n", x);
>>     return 0;
>> }
>>
>> triggers a warning about the format string?  If it's a big a problem
>> as you say it is, that shouldn't be difficult.
>
> It's just that I've seen many references to PRId32 on Linux, including
> online manual pages, which show it as "ld".

That proves nothing at all.  If int32_t is defined as long, PRId32
*should* be "ld".  (On many systems, both int and long are 32 bits;
on such systems, int32_t could sensibly be either int or long.)

Once again, can you cite a specific real-world system where the
definitions of int32_t and PRId32 are *inconsistent*?  Defining them
consistently is so easy that it seems unlikely any implementor
would make that particular mistake.

>>> Thus my suggestion of enhancing printf() instead of trying to suggest
>>> that the standard provide more PRI* like macros.  Let's get rid of the
>>> problem entirely, or at least provide a truely safe and innovative
>>> solution for those who would prefer a better way.
>>
>> You know what?  I might actually agree with whatever point you're
>> trying to make, if I can figure out just what it is.  I've never
>> found any use for the PRI* macros myself.  But your underlying point
>> is obscured by your claims about problems with the PRI* macros that,
>> as far as I can tell, do not actually exist.
>
> 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.

Obviously typedefs defined outside the standard library can't have
corresponding PRI* macros within the standard library.

Once again, the PRI* macros aren't intended to support *all* possible
integer types, so complaining that they don't doesn't make much sense.

> The reason I've harped on PRI* is that their existance would also be
> entirerly unnecessary were something like my proposal implemented, and
> because there are now countless examples of people trying vainly to
> emulate the PRI* macros for their own use, but even more often getting
> it entirely wrong.

And you have yet to show a single concrete example of someone getting it
wrong.  No, don't bother telling me to look for such an example myself;
you're the one making the claim.

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


#695

From"Greg A. Woods" <woods@robohack.org>
Date2011-07-09 16:18 -0700
Message-ID<87mxgncaax.fsf@once.weird.com>
In reply to#672
Keith Thompson <kst-u@mib.org> writes:
> 
> As I recall, your original article had a proposal for extending printf
> format strings.  Perhaps I'll go back and find it.

You should -- that was the point of it after all.  :-)

> Once again, can you cite a specific real-world system where the
> definitions of int32_t and PRId32 are *inconsistent*?

Do you have a really short memory today Keith?  Perhaps you should
review the whole thread,.  :-)

-- 
						Greg A. Woods
						RoboHack

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

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


#702

FromKeith Thompson <kst-u@mib.org>
Date2011-07-09 18:57 -0700
Message-ID<lnliw6x5ha.fsf@nuthaus.mib.org>
In reply to#695
"Greg A. Woods" <woods@robohack.org> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> As I recall, your original article had a proposal for extending printf
>> format strings.  Perhaps I'll go back and find it.
>
> You should -- that was the point of it after all.  :-)
>
>> Once again, can you cite a specific real-world system where the
>> definitions of int32_t and PRId32 are *inconsistent*?
>
> Do you have a really short memory today Keith?  Perhaps you should
> review the whole thread,.  :-)

I've already read the whole thread.  Unless I missed something,
you have *never* cited a specific real-world system on which
those definitions are inconsistent.  The closest you've come is to
mention a system where PRId32 expands to "ld" and you *assumed* that
int32_t is int, an assumption that is almost certainly incorrect.
(If int32_t is defined as long on that system, then it's not an
example that supports your claim.)

Did you not understand my earlier explanation of this?

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


#725

FromKeith Thompson <kst-u@mib.org>
Date2011-07-13 09:37 -0700
Message-ID<lnbowyrvan.fsf@nuthaus.mib.org>
In reply to#702
Keith Thompson <kst-u@mib.org> writes:
> "Greg A. Woods" <woods@robohack.org> writes:
>> Keith Thompson <kst-u@mib.org> writes:
>>> As I recall, your original article had a proposal for extending printf
>>> format strings.  Perhaps I'll go back and find it.
>>
>> You should -- that was the point of it after all.  :-)
>>
>>> Once again, can you cite a specific real-world system where the
>>> definitions of int32_t and PRId32 are *inconsistent*?
>>
>> Do you have a really short memory today Keith?  Perhaps you should
>> review the whole thread,.  :-)
>
> I've already read the whole thread.  Unless I missed something,
> you have *never* cited a specific real-world system on which
> those definitions are inconsistent.  The closest you've come is to
> mention a system where PRId32 expands to "ld" and you *assumed* that
> int32_t is int, an assumption that is almost certainly incorrect.
> (If int32_t is defined as long on that system, then it's not an
> example that supports your claim.)
>
> Did you not understand my earlier explanation of this?

Shall we just assume that you *don't* have any concrete examples
to support your claim?

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


#679

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-07-09 06:46 -0400
Message-ID<iv9bi0$rn$2@dont-email.me>
In reply to#671
On 07/09/2011 02:24 AM, Greg A. Woods wrote:
> Keith Thompson <kst-u@mib.org> writes:
...
> It's just that I've seen many references to PRId32 on Linux, including
> online manual pages, which show it as "ld".

Do you have any reason to justify your assumption that, on the systems
where it's so defined, "ld" is incorrect?
-- 
James Kuyper

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


#684

FromHarald van Dijk <truedfx@gmail.com>
Date2011-07-09 08:09 -0700
Message-ID<02d109ab-91f7-4bde-8650-68cccce7d55f@a31g2000vbt.googlegroups.com>
In reply to#671
On Jul 9, 7:24 am, "Greg A. Woods" <wo...@robohack.org> wrote:
> Keith Thompson <ks...@mib.org> writes:
> > Can you cite a specific real-world system where the definitions of
> > int32_t and PRId32 are inconsistent?  Can you demonstrate that this
> > program:
>
> > #include <stdio.h>
> > #include <inttypes.h>
> > int main(void)
> > {
> >     int32_t x = 42;
> >     printf("x = %" PRId32 "\n", x);
> >     return 0;
> > }
>
> > triggers a warning about the format string?  If it's a big a problem
> > as you say it is, that shouldn't be difficult.
>
> It's just that I've seen many references to PRId32 on Linux, including
> online manual pages, which show it as "ld".

glibc has defined PRId32 as "d" since it was added to inttypes.h back
in 1999. It has not changed since. The link <http://linux.die.net/man/
3/prid32> that you found is the man page from avr-libc. avr-libc
defines int32_t as signed long int.

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


#710

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-07-11 16:00 +0300
Message-ID<87tyatnf9a.fsf@bazspaz.fatphil.org>
In reply to#684
Harald van Dijk <truedfx@gmail.com> writes:
> On Jul 9, 7:24 am, "Greg A. Woods" <wo...@robohack.org> wrote:
> > Keith Thompson <ks...@mib.org> writes:
> > > Can you cite a specific real-world system where the definitions of
> > > int32_t and PRId32 are inconsistent?  Can you demonstrate that this
> > > program:
> >
> > > #include <stdio.h>
> > > #include <inttypes.h>
> > > int main(void)
> > > {
> > >     int32_t x = 42;
> > >     printf("x = %" PRId32 "\n", x);
> > >     return 0;
> > > }
> >
> > > triggers a warning about the format string?  If it's a big a problem
> > > as you say it is, that shouldn't be difficult.
> >
> > It's just that I've seen many references to PRId32 on Linux, including
> > online manual pages, which show it as "ld".

Which doesn't answer either of Keith's questions.

> glibc has defined PRId32 as "d" since it was added to inttypes.h back
> in 1999. It has not changed since. The link <http://linux.die.net/man/
> 3/prid32> that you found is the man page from avr-libc. avr-libc
> defines int32_t as signed long int.

Not that it's important at all, it appears that Dinkumware also have a "ld"
format.
  http://www.dinkumware.com/manuals/?manual=compleat&page=inttypes.html
However, as they have a long type to match, all that does is reinforce
our point that there are no known inconsistencies in extant implementations.

Phil, wondering whether the 'compleat' implies revelling in being different
-- 
"At least you know where you are with Microsoft."
"True. I just wish I'd brought a paddle." -- Matthew Vernon

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


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

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


csiph-web