Re: What is the right way to print a UINTN?


Michael D Kinney
 

Hi Brian,

This is a good idea. I will have to study it some more
to figure out what the EBC versions of these macros would
map to.

Mike

-----Original Message-----
From: Brian J. Johnson [mailto:bjohnson@...]
Sent: Tuesday, September 27, 2016 10:14 AM
To: Andrew Fish <afish@...>; Eugene Cohen <eugene@...>
Cc: Kinney, Michael D <michael.d.kinney@...>; Alexei Fedorov
<Alexei.Fedorov@...>; edk2-devel@... <edk2-devel@...>; Laszlo
Ersek <lersek@...>
Subject: Re: [edk2] What is the right way to print a UINTN?

On 09/27/2016 11:47 AM, Andrew Fish wrote:

On Sep 27, 2016, at 9:03 AM, Cohen, Eugene <eugene@...> wrote:

Printing UINTN with %x *or* with %d are equally bugs.

For X64 / AARCH64 / IA64 builds, they are actual bugs (that happen to
work most of the time).
Feel free to file a Bugzilla on the extensive usage of this in
edk2 [ducking and running]. :)

I'm envisioning having to create a slide in the future for UEFI
training about the proper use of UINTNs and describing "If you think
it may exceed 2^32-1 then upcast to UINT64, otherwise don't worry
about it" and it makes me squirm.
It makes me squirm too. I think the slide should recommend the
casting
that I proposed. ;) "There is no conversion specifier dedicated to
UINTN; the portable way to print it is to cast it to UINT64, then print
it with %Lx."
This is reasonable although I expect to get asked why a lot of the
other code doesn't adhere to this recommendation.
I think this is a historical artifact. The older version of %x in
the EDK (and early edk2) implied UINTN. We hit an issue with C
integer math resulting in an int and that seemed to bork some
toolchains. That is when things changed from UINTN to int. I guess
the cleanup was practical vs. pedantic.
Thanks for the historical context, Andrew. It's interesting to hear,
if very unfortunate.

I've written code in the past which uses a #defined value for the
UINTN format character as a way to work around this issue without
casting everything to 64 bits. Something like:

// Format string for a naturally-sized unsigned integer
#if defined (MDE_CPU_IA32)
#define UINTN_FMT "0x%08x"
#elif defined (MDE_CPU_X64)
#define UINTN_FMT "0x%016lx"
#elif ...
...
#endif

UINTN Val;
Val = Foo ();
DEBUG((DEBUG_INFO, "Value is " UINTN_FMT "\n", Val));


I guess it's a matter of opinion if that's preferable to adding casts;
in my particular situation, I had to print values with that particular
format string in a lot of places, so it was convenient to #define it
once.


Thanks,

Andrew Fish

Thanks,

Eugene
_______________________________________________
edk2-devel mailing list
edk2-devel@...
https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@...
https://lists.01.org/mailman/listinfo/edk2-devel

--

Brian J. Johnson

--------------------------------------------------------------------

My statements are my own, are not authorized by SGI, and do not
necessarily represent SGI's positions.

Join {devel@edk2.groups.io to automatically receive all group messages.