Re: [RFC] convert a host address to a string

Kai Tietz
2009-01-08T13:35:28Z

gdb-patches-owner@sourceware.org wrote on 08.01.2009 14:26:15:

> > Date: Thu, 8 Jan 2009 14:19:11 +0400
> > From: Joel Brobecker <brobecker@adacore.com>
> >
> > > An option would be to use the strategy used by phex_nz() to print
host
> > > addresses. Or we could use PRINTF_HAS_LONG_LONG, and always use
%llx
> > > if it's available.
> >
> > Unfortunately, I don't know how this could be made to work.
> > The problem is that GCC insists that the integer type that we
> > use to cast the host address to must have the same size.
> > At one point, hoping that GCC would kill the wrong branch,
> > I even tried:
> >
> > if (sizeof (void *) == sizeof (long))
> > printf ("0x%lx", (long) address);
> > else
> > printf ("0x%llx", (long long) address);
> >
> > But this didn't work, because GCC complained about the cast
> > in the "if" branch.
>
> Ah, GCC is being a bit too helpful here. Damn!
>
> > Actually, it's only after writing the entire email that I realized
> > that we have another option. See option (3) below.
> >
> > > I'd really like to avoid introducing another macro dealing with
> > > type-size issues if possible. I especially dislike HOST_IS_LLP64
> > > since I fear its existence encourages people to write unportable
code.
> >
> > I can see several solutions:
> >
> > 1. Use %p. To overcome the problem with 0x, we could use
> > two alternatives:
> >
> > a. Import printf from gnulib. I looked at this a while ago,
> > for some other issue, and I immediately stopped, as it
> > looked like it might be a lot of work to do so (printf
> > doesn't come alone, there's a bunch of other routines
> > that printf uses which we probably want).
>
> I'm not very excited about this option. And if the gnulib printf
> doesn't actually implement the Microsoft-invented non-standard format
> specifiers it may even cause us more grief.
>
> > b. Strip the leading "0x" if %p already provides it. In other
> > words:
> >
> > fprintf (buf, "0x%p", address);
> > if (buf[2] == '0' && buf[3] == 'x')
> > buf = buf + 2;
> > return buf;
> >
> > There is no memory management issue in this case, because
> > the buffer we return is more or less static. It's part
> > of a bunch of buffers we cycle through each time we call
> > this routine. The caller never frees the memory we return.
>
> Ugh, this is a bit ugly. And we can't even be sure that there are
> even more variations on the format that %p generates. I wouldn't be
> surprised at all if some platforms would use upper case for the hex
> digits for example.
>
> > 2. Avoid the HOST_IS_LLP64 macro, but still do something similar
> > inside host_address_to_string. Something like:
> >
> > #if defined(WIN64_)
> > fprintf (buf, "0x%llx", (unsigned long long) address);
> > #else
> > fprintf (buf, "0x%lx", (unsigned long) address);
> > #endif
> >
> > This eliminates the likeliness of re-using the HOST_IS_LLP64
> > macro to write non-portable code.
>
> Not really excited about this one either.
>
> > 3. Work through uintptr_t.
> >
> > #ifdef PRINTF_HAS_LONG_LONG
> > fprintf (buf, "0x%llx", (unsigned long long) (uintptr_t)
address);
> > #else
> > fprintf (buf, "0x%lx", (unsigned long) (uintptr_t) address);
> > #endif
>
> This wouldn't be the first place where we'd use a double cast in
> connection with intptr_t/uintptr_t. So I'd say that while this is a
> bit ugly, it's certainly acceptable. It's by far the simplest way to
> fix things.
>
> > I kinda like option 1b as being simple and avoiding the need to
> > cast the address to an integer. Option (3) is my next favorite,
> > but I don't like the fact that we end up doing an unnecessary
> > integer promotion on the 32bit targets.
>
> I'm not really worried about the integer promotion. Printing host
> addresses is a fairly rare operation, and certainly not time critical.
>

Please be aware that %llx isn't valid for x86_64 windows (as it isn't for
32-bit standard). The options 'I' or 'I64' have to be used for those
targets (at least for _WIN64).

Cheers,
Kai

| (\_/) This is Bunny. Copy and paste Bunny
| (='.'=) into your signature to help him gain
| (")_(") world domination.