Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder3.hal-mli.net!news.glorb.com!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post01.iad.highwinds-media.com!newsfe06.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: <874o2vc7ab.fsf@once.weird.com> Cancel-Lock: sha1:i4PPw6oIPpWcaGUsUUOiLUcxMoo= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Lines: 93 NNTP-Posting-Host: 24.67.98.78 X-Complaints-To: internet.abuse@sjrb.ca X-Trace: newsfe06.iad 1310257437 24.67.98.78 (Sun, 10 Jul 2011 00:23:57 UTC) NNTP-Posting-Date: Sun, 10 Jul 2011 00:23:57 UTC Date: Sat, 09 Jul 2011 17:23:56 -0700 Xref: x330-a1.tempe.blueboxinc.net comp.std.c:699 Keith Thompson writes: > > "Greg A. Woods" 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 living on the edge http://www.robohack.ca/