Speaking mainly from a C perspective, since you've tagged [C] and you're using C-style code.
If I am not mistaken, on a 64bit machine, a pointer is equivalent to a number between 0 and 2^64-1.
Well that's a bit tricky. Pointers can be converted to integers and back, but the size required for an integer type to be capable of supporting all possible round-trip pointer-integer-pointer conversions without data loss is unspecified. Implementations are not required to provide such a type.
Moreover, pointers are not required to be represented as integer indexes into a flat address space, and indeed, historically, some implementations have used different representations. It is therefore not correct or safe to assert that a pointer is equivalent to a number, regardless of range.
Note also that this ...
printf("0x%lx", (uintptr_t) -1);
... is unsafe, inasmuch as it assumes that uintptr_t
is unsigned long int
, which is by no means guaranteed to be the case. The safe way to write a format string for a value of type uintptr_t
is:
printf("0x%" PRIxPTR, (uintptr_t) -1);
(Uses inttypes.h
)
Is there any reason why all my objects are (always) given an adress at the begining of the memory space ? Thanks to virtual memory the could be placed (from the program's point of view) basicaly anywhere in the 64bit space.
This is well beyond anything specified by C or C++, but yes, on a virtual-memory machine, your objects could be placed anywhere in the system's virtual address space. Why should they be, however? If your objects are dynamically allocated or have automatic duration then they are likely to be allocated in relatively consistent regions, because the system has regions that it uses for those purposes. If the objects have static duration then they might, in principle, be subject to ASLR, but that depends on the system, the C implementation, compilation options, and other details.
Also why doesn't %p print the full width by default ? (I would expect if to act like 0x%016lx)
Why should it do so? Your expectation is unjustified. printf()
generally does not print leading zeroes unless you explicitly ask it to do so. C does not even require that the output be formatted as a hexadecimal number -- the format is completely implementation-defined.
Edit: Also, is there any reason why 0x018p
is not valid ?
Because the standard explicitly says that the 0
flag character causes undefined behavior when used with the p
conversion specifier. More generally, it produces UB when used with any conversion specifier other than d
, i
, o
, u
, x
, X
, a
, A
, e
, E
, f
, F
, g
, or G
. That's a long list of specifiers, but p
is not on it. If you look carefully, you'll see that it's all the ones that specify conversion to numeric format, which, again, C does not specify p
to do (though some implementations may so specify).