Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any type of pointer can point to anything?

Tags:

c++

pointers

Is this statement correct? Can any "TYPE" of pointer can point to any other type? Because I believe so, still have doubts.

Why are pointers declared for definite types? E.g. int or char?

The one explanation I could get was: if an int type pointer was pointing to a char array, then when the pointer is incremented, the pointer will jump from 0 position to the 2 position, skipping 1 position in between (because int size=2).

And maybe because a pointer just holds the address of a value, not the value itself, i.e. the int or double.

Am I wrong? Was that statement correct?

like image 540
Abhinav Gauniyal Avatar asked Oct 31 '13 15:10

Abhinav Gauniyal


4 Answers

Pointers may be interchangeable, but are not required to be.

In particular, on some platforms, certain types need to be aligned to certain byte-boundaries. So while a char may be anywhere in memory, an int may need to be on a 4-byte boundary.

Another important potential difference is with function-pointers.
Pointers to functions may not be interchangeable with pointers to data-types on many platforms.

It bears repeating: This is platform-specific.

I believe Intel x86 architectures treat all pointers the same.
But you may well encounter other platforms where this is not true.

like image 148
abelenky Avatar answered Oct 21 '22 20:10

abelenky


Every pointer is of some specific type. There's a special generic pointer type void* that can point to any object type, but you have to convert a void* to some specific pointer type before you can dereference it. (I'm ignoring function pointer types.)

You can convert a pointer value from one pointer type to another. In most cases, converting a pointer from foo* to bar* and back to foo* will yield the original value -- but that's not actually guaranteed in all cases.

You can cause a pointer of type foo* to point to an object of type bar, but (a) it's usually a bad idea, and (b) in some cases, it may not work (say, if the target types foo and bar have different sizes or alignment requirements).

You can get away with things like:

int n = 42;
char *p = (char*)&n;

which causes p to point to n -- but then *p doesn't give you the value of n, it gives you the value of the first byte of n as a char.

The differing behavior of pointer arithmetic is only part of the reason for having different pointer types. It's mostly about type safety. If you have a pointer of type int*, you can be reasonably sure (unless you've done something unsafe) that it actually points to an int object. And if you try to treat it as an object of a different type, the compiler will likely complain about it.

Basically, we have distinct pointer types for the same reasons we have other distinct types: so we can keep track of what kind of value is stored in each object, with help from the compiler.

(There have been languages that only have untyped generic pointers. In such a language, it's more difficult to avoid type errors, such as storing a value of one type and accidentally accessing it as if it were of another type.)

like image 35
Keith Thompson Avatar answered Oct 21 '22 22:10

Keith Thompson


Any pointer can refer to any location in memory, so technically the statement is correct. With that said, you need to be careful when reinterpreting pointer types.

A pointer basically has two pieces of information: a memory location, and the type it expects to find there. The memory location could be anything. It could be the location where an object or value is stored; it could be in the middle of a string of text; or it could just be an arbitrary block of uninitialised memory.

The type information in a pointer is important though. The array and pointer arithmetic explanation in your question is correct -- if you try to iterate over data in memory using a pointer, then the type needs to be correct, otherwise you may not iterate correctly. This is because different types have different sizes, and may be aligned differently.

The type is also important in terms of how data is handled in your program. For example, if you have an int stored in memory, but you access it by dereferencing a float* pointer, then you'll probably get useless results (unless you've programmed it that way for a specific reason). This is because an int is stored in memory differently from the way a float is stored.

like image 4
Peter Bloomfield Avatar answered Oct 21 '22 22:10

Peter Bloomfield


Can any "TYPE" of pointer can point to any other type?

Generally no. The types have to be related.

It is possible to use reinterpret_cast to cast a pointer from one type to another, but unless those pointers can be converted legally using a static_cast, the reinterpret_cast is invalid. Hence you can't do Foo* foo = ...; Bar* bar = (Bar*)foo; unless Foo and Bar are actually related.

You can also use reinterpret_cast to cast from an object pointer to a void* and vice versa, and in that sense a void* can point to anything -- but that's not what you seem to be asking about.

Further you can reinterpret_cast from object pointer to integral value and vice versa, but again, not what you appear to be asking.

Finally, a special exception is made for char*. You can initialize a char* variable with the address of any other type, and perform pointer math on the resulting pointer. You still can't dereference thru the pointer if the thing being pointed to isn't actually a char, but it can then be casted back to the actual type and used that way.

Also keep in mind that every time you use reinterpret_cast in any context, you are dancing on the precipice of a cliff. Dereferencing a pointer to a Foo when the thing it actually points to is a Bar yields Undefined Behavior when the types are not related. You would do well to avoid these types of casts at all costs.

like image 1
John Dibling Avatar answered Oct 21 '22 22:10

John Dibling