Pointer to integral conversion

I

icecrime

Hi,

I have a small interrogation concerning pointer to integer conversion:
how is it possible to safely and portably print a memory address ? From
what I understand (according to FAQ 4.14), conversion from pointer to
integral is never never guaranteed. But (correct me if I'm wrong) some
kind of conversion _is_ necessary in order to print the numeric value.

I have taken a look to the gnu libc printf implementation, and it
appears that the void * is being casted into the largest available
integer type. Do I have a standard and portable way to know about this
"largest integer type" ?

Thank you in advance.
 
G

Guest

icecrime said:
Hi,

I have a small interrogation concerning pointer to integer conversion:
how is it possible to safely and portably print a memory address ?

printf("%p", (void *) p);
From
what I understand (according to FAQ 4.14), conversion from pointer to
integral is never never guaranteed. But (correct me if I'm wrong) some
kind of conversion _is_ necessary in order to print the numeric value.

Yes. This conversion may not be available in a standard way, though,
and even if it is, there's no guarantee that %p prints a numeric value.
I have taken a look to the gnu libc printf implementation, and it
appears that the void * is being casted into the largest available
integer type.

That's possible because glibc is not meant to be ported to platforms
where pointers are larger than the largest integer type.
Do I have a standard and portable way to know about this
"largest integer type" ?

In C90, there's (signed/unsigned) long. In C99, there's intmax_t
(signed) and uintmax_t (unsigned), which you get by including
<stdint.h>. These types may be too small to store pointer values. More
appropriate would be intptr_t and uintptr_t, optionally defined in the
same header; when they're not available, intmax_t and uintmax_t
probably won't work either.
 
L

loic-dev

Hi,
I have a small interrogation concerning pointer to integer conversion:
how is it possible to safely and portably print a memory address ? From
what I understand (according to FAQ 4.14), conversion from pointer to
integral is never never guaranteed. But (correct me if I'm wrong) some
kind of conversion _is_ necessary in order to print the numeric value.

Use the "%p" conversion specifier. The libc shall take care of the
internal representation.

HTH,
Loic.
 
R

Richard Bos

icecrime said:
I have a small interrogation concerning pointer to integer conversion:
how is it possible to safely and portably print a memory address ?

You use printf("%p", (void *)your_pointer).
From what I understand (according to FAQ 4.14), conversion from pointer to
integral is never never guaranteed. But (correct me if I'm wrong) some
kind of conversion _is_ necessary in order to print the numeric value.

True, but there's the problem: there is not necessarily a meaningful
numeric value for pointers. Not all computers have a flat memory space.
I have taken a look to the gnu libc printf implementation, and it
appears that the void * is being casted into the largest available
integer type. Do I have a standard and portable way to know about this
"largest integer type" ?

Yes and no. In C89, the largest (unsigned, which is what you want)
integer type is unsigned long. This may not be large enough to represent
all pointer values, though.

In C99, the situation is even more complex. The largest unsigned integer
is uintmax_t, which is required to exist in <stdint.h>; since this must
be at least as large as an unsigned long long, it is more likely to be
large enough for a pointer.
There is also an even better choice in the same header: uintptr_t. A
void pointer can be converted to this type and back without changing
value. The problem with this type is that it's optional. You can find
out if your implementation has it by checking if UINTPTR_MAX is #defined
in <stdint.h>.
For both these types, you can find macros needed to print them safely in
<inttypes.h>; if you #include that header, it also #includes <stdint.h>,
so you don't need to do that as well.

In the end, though, I'd just go with casting the pointer to (void *) and
using "%p". That's portable everywhere.

Richard
 
E

Eric Sosman

icecrime said:
Hi,

I have a small interrogation concerning pointer to integer conversion:
how is it possible to safely and portably print a memory address ? From
what I understand (according to FAQ 4.14), conversion from pointer to
integral is never never guaranteed. But (correct me if I'm wrong) some
kind of conversion _is_ necessary in order to print the numeric value.

You can print the value of a `void*' pointer (but not necessarily
any other kind of pointer) with the "%p" specifier. Whether this is
portable or not depends on what you mean by "portable:" the action of
printing the pointer is portable, but the characters printed are not:
both their identities and their format are implementation-defined.
I have taken a look to the gnu libc printf implementation, and it
appears that the void * is being casted into the largest available
integer type. Do I have a standard and portable way to know about this
"largest integer type" ?

For C90 `[unsigned] long' is the largest integer type, but it is
not guaranteed to be large enough to hold all pointer values. In
C99 you have `intmax_t', but `intptr_t' would be a better choice
for the purpose at hand. Even in C99 there are no guarantees about
how the conversion works, except that it is reversible: If you convert
a `void*' to a `intptr_t' and back again, the result compares equal
to the original. Nothing is specified about the form of the integer
in the middle, or how it is transformed from and to the pointer.
 
K

Keith Thompson

Harald van Dijk said:
printf("%p", (void *) p);

Yes, but only for object pointers. For function pointers, the
conversion to void* may or may not work; it does on many
implementations, but it's not guaranteed. The only general way to
print a function pointer is to look at the bytes making up its
representation; even then, the meaning of those bytes is entirely
implementation-specific.
 
S

Skarmander

Keith said:
Yes, but only for object pointers. For function pointers, the
conversion to void* may or may not work; it does on many
implementations, but it's not guaranteed. The only general way to
print a function pointer is to look at the bytes making up its
representation; even then, the meaning of those bytes is entirely
implementation-specific.
Additionally, a function pointer need not point to object memory, or indeed
to any sort of memory at all. If it's valid and non-null it'll point to a
particular function, but that's all we can portably say.

S.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top