From owner-freebsd-hackers@FreeBSD.ORG Sun Jun 5 21:10:59 2011 Return-Path: Delivered-To: hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2B96F1065673 for ; Sun, 5 Jun 2011 21:10:59 +0000 (UTC) (envelope-from ben@links.org) Received: from mail.links.org (mail.links.org [217.155.92.109]) by mx1.freebsd.org (Postfix) with ESMTP id 96C5A8FC17 for ; Sun, 5 Jun 2011 21:10:58 +0000 (UTC) Received: from [193.133.15.218] (localhost [127.0.0.1]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.links.org (Postfix) with ESMTPS id 63D7733C1E; Sun, 5 Jun 2011 22:10:57 +0100 (BST) Message-ID: <4DEBF0E7.3040304@links.org> Date: Sun, 05 Jun 2011 22:11:03 +0100 From: Ben Laurie User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10 MIME-Version: 1.0 To: Poul-Henning Kamp References: <12271.1307306565@critter.freebsd.dk> In-Reply-To: <12271.1307306565@critter.freebsd.dk> X-Enigmail-Version: 1.1.1 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: hackers@freebsd.org Subject: Re: int64_t and printf X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Jun 2011 21:10:59 -0000 On 05/06/2011 21:42, Poul-Henning Kamp wrote: > In message <4DEBE469.5060305@links.org>, Ben Laurie writes: >> On 05/06/2011 19:21, Poul-Henning Kamp wrote: >>> In message <4DEBC741.1020200@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 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