Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 31 Jan 2001 15:06:43 -0600
From:      Lucas Bergman <lucas@slb.to>
To:        Theo van Klaveren <t.vanklaveren@student.utwente.nl>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: Printf question
Message-ID:  <20010131150643.C28173@billygoat.slb.to>
In-Reply-To: <FHEHJFHKDJMJCKHHPLFGEEMFCCAA.t.vanklaveren@student.utwente.nl>; from t.vanklaveren@student.utwente.nl on Wed, Jan 31, 2001 at 09:31:30PM %2B0100
References:  <FHEHJFHKDJMJCKHHPLFGEEMFCCAA.t.vanklaveren@student.utwente.nl>

next in thread | previous in thread | raw e-mail | index | archive | help
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 <stdio.h>

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010131150643.C28173>