From owner-freebsd-questions Wed Jan 31 13: 9:25 2001 Delivered-To: freebsd-questions@freebsd.org Received: from dsl-64-193-218-89.telocity.com (dsl-64-193-218-89.telocity.com [64.193.218.89]) by hub.freebsd.org (Postfix) with SMTP id 6FFCE37B69B for ; Wed, 31 Jan 2001 13:09:06 -0800 (PST) Received: (qmail 20848 invoked by uid 1000); 31 Jan 2001 21:06:44 -0000 Date: Wed, 31 Jan 2001 15:06:43 -0600 From: Lucas Bergman To: Theo van Klaveren Cc: freebsd-questions@freebsd.org Subject: Re: Printf question Message-ID: <20010131150643.C28173@billygoat.slb.to> Reply-To: lucas@slb.to References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: ; from t.vanklaveren@student.utwente.nl on Wed, Jan 31, 2001 at 09:31:30PM +0100 Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Wed, Jan 31, 2001 at 09:31:30PM +0100, Theo van Klaveren wrote: > > Hello, > > I have a small(?) question about printf. If I have a struct with two 64-bit > integers, defined as follows: > > typedef struct _smbfind_result { > uint64_t r_id; > uint64_t c_id; > . > . > } smbfind_result; > > Now, let's take for example res->r_id=1 and res->c_id=255676. The > following statement: > > printf ("result (result %ld, cid %ld)\n", > res->r_id, res->c_id); > > Outputs "result (result 1, cid 0)", whereas the following: > > printf ("result (result %ld, cid %ld)\n", > (long)res->r_id, (long)res->c_id); > > Outputs "result (result 1, cid 255676)", which is of course the > correct answer. Why are the typecasts required? One would say the > %ld would require printf() to format correctly, which it doesn't. Am > I mixing types or something? First, uint64_t is defined as `unsigned long long', no? Since `%ld' specifies a `long' argument, you've got an implicit conversion from `unsigned long long' to `long' happening. How that happens is going to depend on how your machine stores those types. Enabling compiler warnings helps (unless you're naughty and forget to include stdio.h): % cat foo.c #include typedef unsigned long long uint64_t; struct thingy { uint64_t r_id; uint64_t c_id; }; int main(void) { struct thingy x; struct thingy *res = &x; x.r_id = 1; x.c_id = 255676; printf("result (result %ld, cid %ld)\n", res->r_id, res->c_id); return 0; } % gcc -Wall foo.c foo.c: In function `main': foo.c:19: warning: long int format, different type arg (arg 2) foo.c:19: warning: long int format, different type arg (arg 3) What you probably want is the `%llu' specifier instead of `%ld'. Note that `long long' is a _very_ recent addition to the C standard, so proceed with caution if you want your program to be portable. Lucas To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message