On 05/06/2011 21:42, Poul-Henning Kamp wrote:
> In message <4debe469.5060...@links.org>, Ben Laurie writes:
>> On 05/06/2011 19:21, Poul-Henning Kamp wrote:
>>> In message <4debc741.1020...@links.org>, Ben Laurie writes:
> 
>>> I have therefore resorted to printf'ing any typedefed integer type using
>>> "%jd" and an explicit cast to (intmax_t):
>>>
>>>     printf("%-30s -> %jd -> %s\n", s, (intmax_t)t, buf);
>>
>> My objection to this approach is the lack of type-safety - t could be
>> anything and this would continue to work.
>>
>> Using PRId64 at least ensures that t is of an appropriate type.
> 
> Uhm, no, it doesn't.
> 
> At best it allows the compiler to make well chosen assumptions
> about what the printf(3) function does.
> 
> Printf-format warnings are usually lost as soon as you go through
> stdarg/v*printf, because people don't know they should add
> __printflike() and other nonportable gunk to their prototypes.
> 
> And they are totally lost if you use extended printf formatting
> of any kind, because there is no way to tell the compiler that
> "%Y takes a void *"
> 
> This is basically why the work I did in <printf.h> is practically
> useless.
> 
> But worse: PRId64 only works if you know your variable actually is 64bit.
> 
> If you are trying to write code which works with typedefs on both
> 32 and 64 bit platforms you cannot know this.
> 
> It's all nice and dandy that they made a magic "z" letter for size_t,
> but what about uid_t, gid_t, pid_t, off_t, ino_t, mode_t, nlink_t,
> fflags_t and so on ?
> 
> You will therefore be forced to cast your argument to (int64_t)
> before you can use PRId64 safely on it.
> 
> Now you have messed up the format string without loosing the cast
> and now your code will DTWT once somebody typedefs pid_t to int71_t.
> 
>> Providing a better printf seems like an even smarter idea, e.g.
>>
>>      printf("%-30s -> %I64d -> %s\n", s, t, buf);
> 
> Same problem as above.
> 
> There is no way to do this sanely, without involving the compiler.
> 
> At the very least, the compiler would need to mangle the format
> string, so that you write:
> 
>       printf("%-30?d\n", sometype)
> 
> and the compiler replaces the '?' with whatever is suitable
> for the width of the argument.
> 
> Alternatively, and more useful, would be a type-safe or at least
> type-aware stdarg, so that prinf(3) could ask about the width
> and type of the next argument.
> 
> Both would be wonderful additions to ISO-C but you can produce a
> college fresh-man from scratch starting now, before that happens.
> 
> (See also Bjarnes approx. 1985 discussion of why C++ overloads <<
> instead of providing printf(3)).
> 

Your points are taken.

I note that you didn't react to my other wherein you cast from known
type A to known type B. I supposed it would be smart to also assert that
the cast was non-narrowing.

-- 
http://www.apache-ssl.org/ben.html           http://www.links.org/

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to