-1

I have tried searching about this but without luck. I have read about pointers and used them and I know that pointers to non-class types are only compatible with the same pointer type, like

int* apointer = anotherintpointer;

but this is not possible(not without any explicit conversion)

int* apointer = aFLOATpointer;

I do see the point in not allowing this, but not totally. Like, integers are compatible with floating-points, like int x = afloatvariable;, so why should pointers to int not be compatible with pointers to float?

My main question is: Is there any place where I can read about why those pointers are only compatible with the same pointer type and a place that actually states that this is true, because it is just an assumption from my experience. If you can read about this in the standard, please give me a hint where to read, because I could not find it when I quickly skimmed it. So if anybody could provide me a link or something, it would really be more than awesome.

Edit: Based on the comments, I can see that my use of the word compatible is maybe a little off. What I mean by compatible is that one type is allowed to be assigned another :)

  • You need to read up more on the fundamental properties of low-level types in C++. `float` and `int` types are so wildly different you can't interchange them without conversion. – tadman Jul 25 '17 at 20:28
  • Float and int do not work the same way in the memory. So if your int pointer points to a float and something try to use it like an integer. It will corupt the float. Same goes for a float pointer pointing to an int – litelite Jul 25 '17 at 20:28
  • `integers are compatible with floating-points` what do you mean by compatible? They have a _completely_ different bit-representation, so interpreting a floats bits as an int won't give you anything useful. – tkausl Jul 25 '17 at 20:29
  • What happens when you dereference a pointer? What type will come out if it can point to multiple types? – yizzlez Jul 25 '17 at 20:29
  • @tkausl i think he meant _is implicitly convertible_ – litelite Jul 25 '17 at 20:29
  • "integers are compatible with floating-points" - that's a stretch to say the least. First of all, not all floats are representable as integers. Secondly, not all integers will fit in a float. They are different things, don't just assume you can convert one to the other. – Jesper Juhl Jul 25 '17 at 20:30
  • This is a great question, with a completely non-intuitive answer. I don't understand why people are voting to close it. – Sergey Kalinichenko Jul 25 '17 at 20:34
  • Possibly useless analogy: there's a process to "convert" you into, say, a doctor (i.e. education), but merely claiming that your home is the home of a doctor does not make you one. – molbdnilo Jul 25 '17 at 20:45

2 Answers2

3

Like, integers are compatible with floating-points, so why should pointers to int not be compatible with pointers to float?

Integers are convertible to floating-point numbers (and vice-versa), but if you look at the actual bits that make up the values in RAM, they are very different.

For example, your computer probably represents the integer value 1 with these 32 bits:

10000000 00000000 00000000 00000000

while the "equivalent" floating-point value 1.0f is typically represented with these bits:

00000000 00000000 10000000 00111111

If you set an integer pointer to point to a floating point value (or vice versa), then, you'll find that the bits get badly misinterpreted and you won't get the results you expected. You can try it for yourself if you don't mind a little casting-abuse (note that this code invokes undefined behavior and is for educational purposes only; don't rely on this behavior to be consistent elsewhere and don't do this sort of thing in production code):

 #include <stdio.h>

 int main(int, char **)
 {
    int x   = 1;
    float y = 1;

    float * py = reinterpret_cast<float *>(&x);  // evil!
    printf("y=%f\n", *py);

    int * px = reinterpret_cast<int *>(&y);  // evil!
    printf("x=%i\n", *px);

    return 0;
 }

On my machine, the above code prints out this:

 y=0.000000
 x=1065353216

... which is obviously not what one might naively expect. To avoid unhelpful runtime behavior like this, the compiler prevents you from cross-converting pointer types (unless you absolutely demand it e.g. by using reinterpret_cast<>, in which case you'd better really know what you are doing :))

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • Ahh thanks. But is there something like a rule about this defined by the standard or is it just pure logic(that pointers to non-class types can only point to the same pointer type)? –  Jul 25 '17 at 21:42
  • 1
    I think the rule you're looking for might be this one: https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule – Jeremy Friesner Jul 26 '17 at 01:07
  • Thanks again, it looks like it, but not totally sure yet... However, I have read about and it says that char* can point to any type but whenever I do something like `char* acharp = &aninteger;`, I get the error: "a vlaue of type "int*" cannot be used to initialize an entity of type "char*"". Can you say what I have done wrong? Or would you advise me to start a new question? –  Jul 26 '17 at 09:14
  • I believe what they mean is that it doesn't cause Undefined Behavior to point a char* at another data type; however you still need to make an explicit cast if you want to do it (e.g. char * acharp = reinterpret_cast(&aninteger); ) – Jeremy Friesner Jul 26 '17 at 13:34
1

integers are compatible with floating-points, so why should pointers to int not be compatible with pointers to float?

Integers and floats have very different representation in memory. The only reason they are compatible is that compiler provides some implicit conversion "magic". When you write

float f = someInt;

the compiler inserts CPU instructions for you that convert someInt value to float representation.

The compiler can do this only because it knows at compile time that someInt is an int and f is a float. If you have a pointer to float, and write

float f = *pointerToFloat;

but the pointer is pointing to int, the compiler will think the pointer is pointing to float, because there is no other type associated with pointerToFloat. The compiler must trust you that whatever the pointer is pointing to a float representation, so it would end up re-interpreting an int as a float, with completely unexpected (and undefined) results.

If you can read about this in the standard, please give me a hint where to read

There are two parts of the standard that are relevant to pointer conversion - part 3.7.4.3.2, which explains that safely-derived pointers can be, among other things, the result of a well-defined pointer conversion, and part 4.10, which lists three kinds of pointer conversions relevant to primitive data types.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Ahh now that part makes more sense to me, but what about "the main question"(I know that you already have explained it a bit but still). Thanks! –  Jul 25 '17 at 22:51
  • Oh I just saw that you actually updated your answer. Thanks for the update and I could really use that information. However, what about a place that somewhat directly states that pointers cannot point to object of another type, have you seen such place or know where to look for it, because I cannot find that either? Or is this just the strict alias rules that define that or? Thank you so much for the time :) –  Jul 26 '17 at 15:02
  • @FacPam Pointers can point to objects of wrong type, it's just that they are no longer well-defined. Reading from pointers that are not well-defined is undefined behavior. – Sergey Kalinichenko Jul 26 '17 at 15:04
  • I mean that they cannot point to object of the wrong type **without** explicit conversion(except void*), so if "Pointers can point to objects of wrong type" is true, why can't I do ´char* acharp = &aninteger;´, like without explicit conversion? If so, why doesn't any article state this when they explain about pointers. –  Jul 26 '17 at 15:07
  • @FacPam Assigning pointers without conversion is explained in section 4.10. – Sergey Kalinichenko Jul 26 '17 at 18:00
  • Thanks, but it does not say that pointers *cannot* point to object of another type than the type pointed to, like `int* aa = &afloat;` :/ –  Jul 26 '17 at 20:04
  • 1
    @FacPam Standard does not say what you can't do, they say what you can do. If it's not on the list of what's allowed, it's disallowed. – Sergey Kalinichenko Jul 26 '17 at 20:22
  • One last thing though: So I am about to make some notes and I am not quite sure how I should word this. How would you say in a more formal version that "pointers(except void*) to non-class types cannot point to object of a type that is not matching the pointed-to type without any explicit conversion"? –  Jul 26 '17 at 21:31
  • 1
    @FacPam Pointer assignments for pointers to non-class types require a pointer expression of the same type, possibly without a `const` qualifier. `void*` is compatible with any object pointer type; pointer expressions of other types require an explicit conversion. – Sergey Kalinichenko Jul 26 '17 at 22:39