I am trying to get a grasp of undefined-behavior when violating the strict aliasing rule. I have read many articles on SO in order to understand it. However, one question remains: I do not really understand when two types illegaly alias. cpp-reference states:
Type aliasing
Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:
- AliasedType and DynamicType are similar.
- AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.
- AliasedType is std::byte, (since C++17)char, or unsigned char: this permits examination of the object representation of any object as an array of bytes.
I also found a nice example on SO where I clearly see the issue:
int foo( float *f, int *i ) {
*i = 1;
*f = 0.f;
return *i;
}
int main() {
int x = 0;
std::cout << x << "\n"; // Expect 0
x = foo(reinterpret_cast<float*>(&x), &x);
std::cout << x << "\n"; // Expect 0?
}
int
and float
are non-similar types and this program possibly wreaks havoc. What I fail to see and understand is the following modification:
struct A
{
int a;
};
struct B
{
int b;
};
A foo( A *a, B *b ) {
a->a = 1;
b->b = 0;
return *a;
}
int main() {
A a;
a.a = 0;
std::cout << a.a << "\n"; // Expect 0
a = foo(&a, reinterpret_cast<B*>(&a));
std::cout << a.a << "\n"; // Expect 0?
}
Are A
and B
similar types and everything is fine, or are they illegaly aliasing and I have undefined-behavior. And if it is legal, is this because A
and B
are aggregates (if yes, what would I have to change to make it undefined-behavior)?
Any heads-up and help would be very appreciated.
EDIT On the issue of being duplicate
I am aware of this post, but I do not see where they clarify what types are similar. At least not to an extend that I would understand it. Therefore it would be kind if you would not close this question.
A
andB
are unrelated types. – UnwaryC
documentation for types references "Compatible types" en.cppreference.com/w/c/language/type ; theC++
documentation does not en.cppreference.com/w/cpp/language/type . So Compatible Types is not relevant toC++
and the duplicate link explains everything else. In this area of what is an Object and how it can be manipulated/referenced there are significant differences betweenC
andC++
. Mixing terms from the 2 standards can lead to confusion. – Uchish