T
Taras_96
Hi everyone,
I was experimenting with static_cast and reinterpret cast
#include <iostream>
struct A1 { int a; };
struct A2 { double d; };
struct B : public A1, A2
{
int v;
};
int main()
{
// one B object
B b;
// two A2 pointers
A2 * p1;
A2 * p2;
// set both pointers to &b
p1 = static_cast<A2*>(&b);
p2 = reinterpret_cast<A2*>(&b);
// same type, same B object...
// but point to different addresses:
std::cout << "p1: " << p1 << "\n";
std::cout << "p2: " << p2 << "\n";
// the pointers are not equal
assert (p1 == p2); // fails
}
Program Output:
p1: 0xbffff97c
p2: 0xbffff978
Assertion failed: (p1 == p2), function main, file test.cc, line
30.
Abort trap
AFAICT, the difference between the two casts is that static_cast knows
that you're casting down, so it adjusts the value of the pointer
accordingly. reinterpret_cast is just a brute cast.
Previous to this, I thought that different pointer types to the same
underlying object would still store the same address, but the
differing pointer types was more of an indication to the compiler what
expressions the pointer could support. It seems from this experiment
that this is incorrect. Is the reason why the derived pointer moves up
in memory is because of the memory layout, something like this:
TOP OF STACK
------------ <- pointer to derived class
derived members can also 'see' base class members,
. if we think of visibility
. as extending downwards
------------ <- pointer to base can not 'see' derived
members
base members
------------
BOTTOM OF STACK
Is this even defined in C++, or is it implementation specific?
Interestingly when you assign a derived pointer to a base pointer, the
value stored doesn't change, even with a static_cast. This is more
inline with how I thought pointers would originally behave.
So casting from a base to a derived will change the value stored by
the pointer, but casting (or assigning) from a derived to a base will
not change the value. Is there a reason for this?
Thanks
Taras
I was experimenting with static_cast and reinterpret cast
#include <iostream>
struct A1 { int a; };
struct A2 { double d; };
struct B : public A1, A2
{
int v;
};
int main()
{
// one B object
B b;
// two A2 pointers
A2 * p1;
A2 * p2;
// set both pointers to &b
p1 = static_cast<A2*>(&b);
p2 = reinterpret_cast<A2*>(&b);
// same type, same B object...
// but point to different addresses:
std::cout << "p1: " << p1 << "\n";
std::cout << "p2: " << p2 << "\n";
// the pointers are not equal
assert (p1 == p2); // fails
}
Program Output:
p1: 0xbffff97c
p2: 0xbffff978
Assertion failed: (p1 == p2), function main, file test.cc, line
30.
Abort trap
AFAICT, the difference between the two casts is that static_cast knows
that you're casting down, so it adjusts the value of the pointer
accordingly. reinterpret_cast is just a brute cast.
Previous to this, I thought that different pointer types to the same
underlying object would still store the same address, but the
differing pointer types was more of an indication to the compiler what
expressions the pointer could support. It seems from this experiment
that this is incorrect. Is the reason why the derived pointer moves up
in memory is because of the memory layout, something like this:
TOP OF STACK
------------ <- pointer to derived class
derived members can also 'see' base class members,
. if we think of visibility
. as extending downwards
------------ <- pointer to base can not 'see' derived
members
base members
------------
BOTTOM OF STACK
Is this even defined in C++, or is it implementation specific?
Interestingly when you assign a derived pointer to a base pointer, the
value stored doesn't change, even with a static_cast. This is more
inline with how I thought pointers would originally behave.
So casting from a base to a derived will change the value stored by
the pointer, but casting (or assigning) from a derived to a base will
not change the value. Is there a reason for this?
Thanks
Taras