Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to kernel printf a int64_t?

87 views
Skip to first unread message

Rick Macklem

unread,
Oct 30, 2014, 5:01:53 PM10/30/14
to Freebsd hackers list
Hi,

I feel kinda dumb asking this, but...
int64_t i;

printf("%qd\n", (u_quad_t)i);

works but looks dorky, to put it technically;-).
Is there a better way to printf() a int64_t in the kernel?

Thanks for any answers, rick
_______________________________________________
freebsd...@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hacke...@freebsd.org"

Eric van Gyzen

unread,
Oct 30, 2014, 8:54:07 PM10/30/14
to Rick Macklem, Freebsd hackers list
On 10/30/2014 17:01, Rick Macklem wrote:
> I feel kinda dumb asking this, but...
> int64_t i;
>
> printf("%qd\n", (u_quad_t)i);
>
> works but looks dorky, to put it technically;-).
> Is there a better way to printf() a int64_t in the kernel?

The ANSI C way would be:

#include <machine/_inttypes.h>

int64_t i;
printf("%"PRId64"\n", i);

It's probably bad form to directly #include a file name with an
underscore into an implementation file, but I don't see any other way.
Maybe we could create a <sys/inttypes.h> that #includes the necessary
files to be a kernel equivalent of <inttypes.h>.

Eric

Tim Kientzle

unread,
Oct 31, 2014, 1:10:29 AM10/31/14
to Rick Macklem, Freebsd hackers list

On Oct 30, 2014, at 2:01 PM, Rick Macklem <rmac...@uoguelph.ca> wrote:

> Hi,
>
> I feel kinda dumb asking this, but...
> int64_t i;
>
> printf("%qd\n", (u_quad_t)i);
>
> works but looks dorky, to put it technically;-).
> Is there a better way to printf() a int64_t in the kernel?

I often use the following to print large integers:

printf(“%jd\n”, (intmax_t)i);

Tim

Julian Elischer

unread,
Nov 1, 2014, 9:23:26 PM11/1/14
to Tim Kientzle, Rick Macklem, Freebsd hackers list
On 10/31/14, 1:09 PM, Tim Kientzle wrote:
> On Oct 30, 2014, at 2:01 PM, Rick Macklem <rmac...@uoguelph.ca> wrote:
>
>> Hi,
>>
>> I feel kinda dumb asking this, but...
>> int64_t i;
>>
>> printf("%qd\n", (u_quad_t)i);
>>
>> works but looks dorky, to put it technically;-).
>> Is there a better way to printf() a int64_t in the kernel?
> I often use the following to print large integers:
>
> printf(“%jd\n”, (intmax_t)i);
the "cannonical' way is to use PRIu64 and friends, but some people
seem to have a problem with doing that.

Paul Koch

unread,
Nov 1, 2014, 10:02:18 PM11/1/14
to Julian Elischer, Freebsd hackers list
On Sun, 02 Nov 2014 09:23:04 +0800
Julian Elischer <jul...@freebsd.org> wrote:

> On 10/31/14, 1:09 PM, Tim Kientzle wrote:
> > On Oct 30, 2014, at 2:01 PM, Rick Macklem <rmac...@uoguelph.ca> wrote:
> >
> >> Hi,
> >>
> >> I feel kinda dumb asking this, but...
> >> int64_t i;
> >>
> >> printf("%qd\n", (u_quad_t)i);
> >>
> >> works but looks dorky, to put it technically;-).
> >> Is there a better way to printf() a int64_t in the kernel?
> > I often use the following to print large integers:
> >
> > printf(“%jd\n”, (intmax_t)i);
>
> the "cannonical' way is to use PRIu64 and friends, but some people
> seem to have a problem with doing that.

We've always used the PRIxxx types when coding for both 32/64 platforms,
but it would have been really nice to have a standard way for time_t.
Something like PRItt

Paul.
--
Paul Koch | Founder, CEO
AKIPS Network Monitor
http://www.akips.com
Brisbane, Australia

Rick Macklem

unread,
Nov 1, 2014, 10:14:57 PM11/1/14
to Julian Elischer, Freebsd hackers list
Julian Elischer wrote:
>
> On 10/31/14, 1:09 PM, Tim Kientzle wrote:
>
>
> On Oct 30, 2014, at 2:01 PM, Rick Macklem <rmac...@uoguelph.ca>
> wrote:
>
> Hi,
>
> I feel kinda dumb asking this, but...
> int64_t i;
>
> printf("%qd\n", (u_quad_t)i);
>
> works but looks dorky, to put it technically;-).
> Is there a better way to printf() a int64_t in the kernel? I often
> use the following to print large integers:
>
> printf(“%jd\n”, (intmax_t)i); the "cannonical' way is to use
> PRIu64 and friends, but some people seem to have a problem with
> doing that.
>
Ok, so now I need to ask another dumb question.
How do you do this in the kernel?
(I can see them defines in <machine/_inttypes.h>, but including that
doesn't help, which isn't surprising since PRIu64 is in a string
and won't be recognized as a macro.)

Oh, and is intmax_t going to be int64_t on all arches?

Thanks, rick

Julian Elischer

unread,
Nov 1, 2014, 11:20:27 PM11/1/14
to Rick Macklem, Freebsd hackers list
On 11/2/14, 10:14 AM, Rick Macklem wrote:
> Julian Elischer wrote:
>> On 10/31/14, 1:09 PM, Tim Kientzle wrote:
>>
>>
>> On Oct 30, 2014, at 2:01 PM, Rick Macklem <rmac...@uoguelph.ca>
>> wrote:
>>
>> Hi,
>>
>> I feel kinda dumb asking this, but...
>> int64_t i;
>>
>> printf("%qd\n", (u_quad_t)i);
>>
>> works but looks dorky, to put it technically;-).
>> Is there a better way to printf() a int64_t in the kernel? I often
>> use the following to print large integers:
>>
>> printf(“%jd\n”, (intmax_t)i); the "cannonical' way is to use
>> PRIu64 and friends, but some people seem to have a problem with
>> doing that.
>>
> Ok, so now I need to ask another dumb question.
> How do you do this in the kernel?
> (I can see them defines in <machine/_inttypes.h>, but including that
> doesn't help, which isn't surprising since PRIu64 is in a string
> and won't be recognized as a macro.)

you use it with string concatenation.
like:

printf (" this is a 64 it unsigned value: %" PRIu64 " and I just
printed it\n", thingy64);

After substitution the compiler sees
" this is a 64 it unsigned value: %" "llu" " and I just printed it\n"
which simplifies to:
" this is a 64 it unsigned value: %llu and I just printed it\n"

due to concatenation. (note I didn't actually look what PRIu64
evaluates to)

Ian Lepore

unread,
Nov 1, 2014, 11:58:44 PM11/1/14
to Julian Elischer, Freebsd hackers list, Rick Macklem
Which is exactly the explanation for why "some people seem to have a
problem with doing that." "Some people" would be "anyone who thinks it
should be possible to read code as well as write it." This may be more
correct in some pedantic sense, but %j and a cast is more readable.

-- Ian

Rick Macklem

unread,
Nov 2, 2014, 7:48:31 AM11/2/14
to Ian Lepore, Freebsd hackers list
Yes, thanks. I'll admit to thinking exactly the same thing.
I guess I'll use %j.

Thanks everyone for your help, rick

Julian Elischer

unread,
Nov 2, 2014, 11:04:43 AM11/2/14
to Rick Macklem, Ian Lepore, Freebsd hackers list
then your code could be wrong in some cases..

PRIu64 specifies that the value will always be 64 bits (unsigned) on
every architecture.
If that's NOT true then yes, use a type (e.g. %d) that varies here and
there.
If your value will ALWAYS be 64 but then PRIu64 describes what it is
much better than
%j, because you need to know what %j expects on every architecture your
code may ever run on.

In my own opinion, PRIu64 is much more readable than %j because the size
and expected signed/unsigned characterisitics are right there, where
%randomletter is exactly that.. completely random, requiring that the
reader go
consult a man page first before reading code for any given architecture.

Julian Elischer

unread,
Nov 2, 2014, 11:08:56 AM11/2/14
to Ian Lepore, Freebsd hackers list, Rick Macklem
On 11/2/14, 11:58 AM, Ian Lepore wrote:
> On Sun, 2014-11-02 at 11:20 +0800, Julian Elischer wrote:
>>
> Which is exactly the explanation for why "some people seem to have a
> problem with doing that." "Some people" would be "anyone who thinks it
> should be possible to read code as well as write it." This may be more
> correct in some pedantic sense, but %j and a cast is more readable.
Actually I don't believe that to be true, because casting can actually
change the
value. (truncation, sign change etc.)
If you really want to be sure to see what you should. then use
PRImumble...
or be sure of what printf is going to do on every architecture your code
is going to ever run on in the future..
> -- Ian

Ian Lepore

unread,
Nov 2, 2014, 11:35:59 AM11/2/14
to Julian Elischer, Freebsd hackers list, Rick Macklem
The recommendation was "%j and a cast" not just %j. The cast will
ensure that the size of the argument matches the size of the format.

> PRIu64 specifies that the value will always be 64 bits (unsigned) on
> every architecture.
> If that's NOT true then yes, use a type (e.g. %d) that varies here and
> there.
> If your value will ALWAYS be 64 but then PRIu64 describes what it is
> much better than
> %j, because you need to know what %j expects on every architecture your
> code may ever run on.
>

It is well-known what the %j size modifier expects on every
architecture: the size of a value of type [u]intmax_t, which is what
the corresponding argument cast provides. It is a given that
[u]intmax_t is able to represent all other integer types of the
corresponding signedness.

> In my own opinion, PRIu64 is much more readable than %j because the size
> and expected signed/unsigned characterisitics are right there, where
> %randomletter is exactly that.. completely random, requiring that the
> reader go
> consult a man page first before reading code for any given architecture.
>

I'm willing to be proven wrong that %j and the corresponding [u]intmax_t
cast will provide the wrong result in some case. But the proof has to
be in the form of something other than "I disagree with you on which one
is more readable". You seem to be conflating correctness of operation
with stylistic opinion in your reply (sorry if that's not your intent
and the conflation is only in my head).

-- Ian

Tim Kientzle

unread,
Nov 2, 2014, 12:24:06 PM11/2/14
to Paul Koch, Freebsd hackers list

> On Nov 1, 2014, at 6:46 PM, Paul Koch <paul...@akips.com> wrote:
>
> On Sun, 02 Nov 2014 09:23:04 +0800
> Julian Elischer <jul...@freebsd.org> wrote:
>
>> On 10/31/14, 1:09 PM, Tim Kientzle wrote:
>>> On Oct 30, 2014, at 2:01 PM, Rick Macklem <rmac...@uoguelph.ca> wrote:
>>>
>>>> int64_t i;
>>>>
>>>> printf("%qd\n", (u_quad_t)i);
>>>>
>>>> Is there a better way to printf() a int64_t in the kernel?
>>>
>>> printf(“%jd\n”, (intmax_t)i);
>
> We've always used the PRIxxx types when coding for both 32/64 platforms,
> but it would have been really nice to have a standard way for time_t.
> Something like PRItt

This is the major reason I prefer the intmax_t cast approach: the PRI* macros only support a small handful of basic integer types.

The intmax_t cast approach only requires you to know whether it's signed (%jd with intmax_t) or unsigned (%ju with uintmax_t).


> On Nov 1, 2014, at 7:14 PM, Rick Macklem <rmac...@uoguelph.ca> wrote:

> Oh, and is intmax_t going to be int64_t on all arches?

Yes, until we start supporting 128-bit arithmetic. So the only runtime cost for this approach is that it might have to widen the value. (Given the cost of printf in general, that's likely not a problem.)

Tim

Poul-Henning Kamp

unread,
Nov 2, 2014, 1:02:16 PM11/2/14
to Tim Kientzle, Freebsd hackers list, Paul Koch
--------

>> We've always used the PRIxxx types when coding for both 32/64 platforms,
>> but it would have been really nice to have a standard way for time_t.
>> Something like PRItt

That road leads to madness, because now both the reader and the writer
needs to remember what the PRIxx is for inode_t, socklen_t and so on.

In no time you've run out of 'xx' and some camelCaseContrarian will
start using PRI_inode_t "for readability" and... ARGH!

Casting to [u]intmax_t and using %j is horrible, but not nearly as
horrible as any other currently available option.

The *right* solution, could only exist if ISO-C had consisted of
actual C programmers: A varargs definition which transferred both
argument and it's type, so that printf wouldn't need any size
integers at all, but could tell by itself.

The resulting increase in code safety and robustness alone would
make this worth the effort to implement.

--
Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
p...@FreeBSD.ORG | TCP/IP since RFC 956
FreeBSD committer | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.

Ian Lepore

unread,
Nov 2, 2014, 1:06:15 PM11/2/14
to Poul-Henning Kamp, Paul Koch, Freebsd hackers list
On Sun, 2014-11-02 at 18:00 +0000, Poul-Henning Kamp wrote:
> --------
>
> >> We've always used the PRIxxx types when coding for both 32/64 platforms,
> >> but it would have been really nice to have a standard way for time_t.
> >> Something like PRItt
>
> That road leads to madness, because now both the reader and the writer
> needs to remember what the PRIxx is for inode_t, socklen_t and so on.
>
> In no time you've run out of 'xx' and some camelCaseContrarian will
> start using PRI_inode_t "for readability" and... ARGH!
>
> Casting to [u]intmax_t and using %j is horrible, but not nearly as
> horrible as any other currently available option.
>
> The *right* solution, could only exist if ISO-C had consisted of
> actual C programmers: A varargs definition which transferred both
> argument and it's type, so that printf wouldn't need any size
> integers at all, but could tell by itself.
>
> The resulting increase in code safety and robustness alone would
> make this worth the effort to implement.
>

VAX/VMS pass-by-descriptor comes back to life in the 21st century!

-- Ian

Rick Macklem

unread,
Nov 2, 2014, 6:02:47 PM11/2/14
to Ian Lepore, Freebsd hackers list
Yes, I understood that (just didn't state it in the above).

Thanks, rick
0 new messages