int *x = 3;
This is invalid (a constraint violation), and a conforming compiler is required to issue a diagnostic, and may reject it altogether. You cannot use an integer value to initialize a pointer (except for the special case of 0
, which is a null pointer constant).
If a compiler happens to accept it it will probably treat it as equivalent to:
int *x = (int*)3;
which causes the pointer x
to point to address 3
in memory. This is almost certainly nonsensical.
Given that x
and y
are initialized with the same expression (and assuming your code isn't rejected), it's not at all surprising that x == y
is true.
Dereferencing x
has undefined behavior; (int*)3
is very probably not a valid address, because it's outside your program's legal addressing space and/or because it's misaligned. But if *x
happens to "work" and yield a value, it's also not surprising that *x == *y
is true. It's possible that the compiler recognized that x == y
and therefore concluded that *x == *y
. You might determine that by examining the generated code. But it really doesn't matter; once your program's behavior is undefined, quite literally anything can happen (or rather, the language standard permits literally anything to happen; the laws of physics might have something else to say about it).
You should have gotten a warning for both declarations. If you did, you should heed it. If you didn't, you should find out how to increase the warning levels for your compiler.