Why is the initialization of lp illegal?
int i = 42;
long *lp = &i;
Xcode prompts that I cannot initialize a variable of type 'long *' with an rvalue of type 'int *'.
Why?
Why is the initialization of lp illegal?
int i = 42;
long *lp = &i;
Xcode prompts that I cannot initialize a variable of type 'long *' with an rvalue of type 'int *'.
Why?
Your Xcode is on point, those are different types, it is indeed an illegal initialization, C++ does not allow for assignment (or initialization) of pointers with different types.
That said, you can explicitly convert the assignee:
int i = 42;
long *lp = reinterpret_cast<long*>(&i);
About your seach for reasoning, I'll say those are the rules of the language, they are there to protect you (and your program), not to make your job more difficult, a pointer to long used to operate (dereference, increment, etc.) in an address which is used to store an int will invoke undefined behavior. A compiler is not obliged to treat pointers of different types in the same way. Differences in size, alignment, etc. can occur.
As largest_prime_is_463035818 stated the obligation to explicitly cast tries to prevent mistakes.
This, however, only allows you to compile your program, it doesn't remove the possibility of it being ill-formed.
int i = 42;
int *p = &i;
long *lp = reinterpret_cast<long*>(&i);
long *lpc = (long*)(&i);
std::cout << "int pointer => " << *p << "\n"; // fine, prints 42
std::cout << "long pointer => " << *lp << "\n"; // not fine, prints random vaue *
std::cout << "long pointer 2 => " << *lpc << "\n"; // not fine, same *
As you can see in the example above your compiler was right, that is indeed a problematic cast, tricking the compiler to allow the conversion made the program compile, but fail to produce a consistent result.
* I also tried this in a Windows platform and the results were good, maybe because a long in my platform is only 4 bytes, same as an int, maybe not, the point is, you only should do this when you are absolutely certain that the types are interchangeable.