Given the following code:
struct Tag {};
struct X {
// Tag t; // if not commented it shouldn't be pointer-interconvertible
int k;
};
int fn(const X& x, int& p) {
int i = x.k;
p = 2;
return i + x.k;
}
The generated code is:
fn(X const&, int&):
mov eax, DWORD PTR [rdi]
mov DWORD PTR [rsi], 2
add eax, DWORD PTR [rdi]
ret
Here the compiler assumes aliasing.
If member t
is not present, the types X
and int
are pointer-interconvertible. As so, the compiler must generate code as if the references could alias.
But if member t
is present, they should no longer be pointer-interconvertible and code for the non-aliased case should be generated. But in both cases the code is identical except the relative address of member k
.
The assembler:
fn(X const&, int&):
mov eax, DWORD PTR [rdi+4]
mov DWORD PTR [rsi], 2
add eax, DWORD PTR [rdi+4]
ret
As an counter-example
template<typename T>
struct X {int k; };
int fn(X<struct A>& x, X<struct B>& p) {
int i = x.k;
p.k = 2;
return i + x.k;
}
in the above version the generated code assumes no aliasing, but the types are pointer-interconvertible.
fn(X<A>&, X<B>&):
mov eax, DWORD PTR [rdi]
mov DWORD PTR [rsi], 2
add eax, eax
ret
Can anyone explain this?
Here
int fn(const X& x, int& p) {
int i = x.k;
p = 2;
return i + x.k;
}
X::k
is int
,p
is a reference to int
. p
can be a reference to x.k
.
On the other hand, here:
int fn(X<struct A>& x, X<struct B>& p) {
int i = x.k;
p.k = 2;
return i + x.k;
}
X<struct A>
and X<struct B>
are distinct types. There is no way to have x
and p
or parts of it refer to the same object.
But what if k is private and X has operator int() const returning k ?
Then nothing changes. Sloppy speaking, you need a reference/pointer to get potential aliasing. For example
struct G {};
struct H { G* g; }
void foo(G* a,H b);
Here b.g
and a
can point to the same G
(note that this is the case no matter if b
is passed by value, reference or pointer). In your example...
template<typename T>
struct X {int k; };
int fn(X<struct A>& x, X<struct B>& p)
.. the only references are x
and p
. They refer to objects of different types, aka different objects.