3

So, a void pointer is a generic pointer that can point to any of the chars or ints later, right? But it is, however, a pointer. However, this compiles without any error:

void* ptr; 
long var;
ptr = (void*)var;

Why is it possible here to typecast a long to a pointer? Shouldn't it give an error? Note that this also works if var was an int or char.

Also, the below snippet works if the var was long!

cout<<(long)ptr;

However, this doesn't work if var was an int or char. I don't know what to make of it. I am using 64 bit Linux machine.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Sahil
  • 359
  • 2
  • 5
  • 13

3 Answers3

2

Because a pointer is a numerical reference to a memory location, and thus can be cast as a numerical value. In many cases, converting between them is much the same. For example, if I had a 32-bit memory location like 0x3E103A08 (pointers are usually viewed in hex form), that hex representation would be an unsigned integer equivalent of 1041250824. To get more detailed, a 32-bit pointer is just 4 bytes, and so is a 32-bit unsigned integer. In fact, at the CPU level, CPU registers are used - some like pointers, and some for calculations - all of which (in my past developing in ASM) are more like integer variables under the hood.

James Wilkins
  • 6,836
  • 3
  • 48
  • 73
  • The question doesn't mention or illustate "member pointer"s though - only `void*`s to non-member variables, but your basic point is right: memory addresses are just numbers, and if you ask the compile to assume there's an address in an integral variable, or move an address into one, why should it second guess you? – Tony Delroy Apr 21 '15 at 04:56
  • Sorry, my mind was split between something else I was writing. I didn't mean member at all. ;) (typo) – James Wilkins Apr 21 '15 at 04:57
  • The part about hex/dec is strange. It´s the same number. Your post sounds like hex is for pointers, decimal for `int`. (And no, pointers are not *generally* viewed in hex form.) – deviantfan Apr 21 '15 at 04:58
  • That's because most times pointers are viewed in hex form, not integer. – James Wilkins Apr 21 '15 at 04:59
2

It works, because pointers are in fact memory addresses, which in turn are represented by unsigned integer number (address).

Note, that long is usually 4-byte long, so it will not be able to hold memory address, if you switch to 64-bit platform (where pointers are 64-bit / 8 byte long). In this case, converting pointer to int/long will truncate (and thus, invalidate) its content.

To store address value, use uintptr_t (or signed version, intptr_t), as described here:

intptr_t, uintptr_t

Integer type capable of holding a value converted from a void pointer and then be converted back to that type with a value that compares equal to the original pointer.

Optional: These typedefs may not be defined in some library implementations.*

These types are optional, but available on most implementations. Even if they are not present, there should be platform-specific type defined for storing memory addresses.

Oh, and your point about conversions is not quite right - every integer (signed or unsigned) value can be converted to pointer (of any type, including void*) via explicit conversion. It also works the other way around.

Mateusz Grzejek
  • 11,698
  • 3
  • 32
  • 49
  • `intptr_t` is standard in `` – Basile Starynkevitch Apr 21 '15 at 05:11
  • @BasileStarynkevitch **1.** Technically, there is no such thing like `` in C++ (it is ``, which was linked in my answer). **2.** `` is a C++ 11 feature. **3.** [Documentation page for says, that both these types are optional](http://www.cplusplus.com/reference/cstdint/). – Mateusz Grzejek Apr 21 '15 at 05:15
  • My mistake. I thought OP was talking of C, not C++ – Basile Starynkevitch Apr 21 '15 at 05:16
  • 1
    no, `long` is 8-byte long on most POSIX systems http://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models – phuclv Apr 21 '15 at 05:45
  • @LưuVĩnhPhúc Read carefully. I wrote **usually** - MS Windows uses `LLP64` data model, which define `long` as 4-byte long. And since MS systems have ~90% usage share on desktop, that's what **usually** means to me. – Mateusz Grzejek Apr 21 '15 at 07:47
0

As a pointer contains addresses, and an address is a (integer-like) number, you could do this,
like you can cast int to long or long to int. The explicit cast tells the compiler that you´re aware of potential problems, so it won´t give you a warning.

However, it´s not guaranteed at all that a long can hold the same value range like a pointer,
so just don´t use long for addresses.

deviantfan
  • 11,268
  • 3
  • 32
  • 49