Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder3.hal-mli.net!nx01.iad01.newshosting.com!209.197.12.246.MISMATCH!nx02.iad01.newshosting.com!newshosting.com!69.16.185.16.MISMATCH!npeer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post01.iad.highwinds-media.com!newsfe07.iad.POSTED!00000000!not-for-mail Newsgroups: comp.std.c Subject: Re: PRI* considered harmful User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.3 (berkeley-unix) References: <87mxgqhk3x.fsf@once.weird.com> From: "Greg A. Woods" X-Face: .}E4CW({2'v<\JefgY&(9#RJD?~_7.KTC$+RklqwlB/<)^)~X0i*J?m)SXpHA8'9FHn5Fz*eVTH5=_C>]XK#"dLOyD`#tbEh1_8v-hwwR{.X)+b-!\4mM] 1HqG#"@VSI$1MNvRk\4>qsCclW|Ns4V/2poz=gS-+~m8\%5eVq]a\3.>T>U/f8A Message-ID: <87box6hdaj.fsf@once.weird.com> Cancel-Lock: sha1:bhPBLAR+bXtB/RyYUYB6dI0uFV4= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Lines: 69 NNTP-Posting-Host: 24.67.98.78 X-Complaints-To: internet.abuse@sjrb.ca X-Trace: newsfe07.iad 1310016373 24.67.98.78 (Thu, 07 Jul 2011 05:26:13 UTC) NNTP-Posting-Date: Thu, 07 Jul 2011 05:26:13 UTC Date: Wed, 06 Jul 2011 22:26:12 -0700 Xref: x330-a1.tempe.blueboxinc.net comp.std.c:598 William Ahern writes: > > Greg A. Woods wrote: > > 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. > > time_t could be also be double, not just an integer. This is why difftime() > exists. Note that it returns a double. PRI-type macros can't really solve > the problem because of the different format specifications between double > and integer types. I personally think it would be insane for any host environment to try to make time_t a non-integer type, but yes, that's another aspect of PRI* considered harmful :-) > The proper answer is strftime(). Nope -- time_t is just symptomatic of the problem -- there are other typedef names in the standard (wchar_t for example), and indeed dozens of non-standard similar names in any real-world implementation. Besides, strftime() (at least in C99) cannot so far as I know print the canonical numerical value of a time_t! Do you propose a strf*() for every one? Especially when for most of them the numerical value is the only way they are printed? I think you may have missed my point entirely! I want to get rid of (deprecate) PRI* entirely, thus my topic heading. The _main_ argument about the insanity of printf(), and all the confusion it has caused generations of C programmers, has always been about getting the right format characters to match the sign and the size of integer parameters. Everything else about printf() is really quite trivial in comparison and can be taught quite easily. It's easy to tell a student that a string is not an integer, etc., but you can see confusion about sign and size of integer types vs. printf() everywhere, all of the time. This (i.e. really all of stdarg) is the one place where the true low-level nature of C still shines through with unbridled enthusiasm. This isn't necessarily a bad thing, but we have never really truly done anything useful to help at least make the worst parts, for the worst standard functions, any better. My proposal doesn't mess with the language per se -- I just add a facility to printf() (and I suppose scanf()) which would allow the programmer to trivially ensure the format strings always match the magnitude and sign of the values no matter what some silly maintainer might do to the typedefs (within reason -- i.e. within keeping to integer types). Indeed if it were not for the legacy I would require that all parameters for all format characters for all numerical types always be accompanied by a sign flag and an indication of how many "units" should be extracted or pushed from/to the parameter list by the likes of printf() and scanf(). If you want to go one further then include the "storage format" in with the sign flag too (int, float, or pointer). -- Greg A. Woods RoboHack living on the edge http://www.robohack.ca/