Re: Foward decleration casting craziness
speedplane wrote:
Hi there...
I just found a bug in a very well known compiler and I was wondering if
others have found the same problem. Consider the code snippet
class C; // Foward decleration
class A {
public:
// Here we cast to C but we don't know how to cast an A to
C* getAasC{ return (C*)this; };C
int a;
};
Note that this code will compile (in my compiler at least) even though
it does not know how to cast an A to a C. In another file say we define
C:
class B {
public:
int b;
};
class C : public B, A {
public;
int c;
}
In the first code snippet, the compiler does not know how to cast an A
to a C. Therefore it does a reinterpret cast instead of a static cast.
Consider the following code:
A * a = new C();
a->a = 50;
printf("A: %d, C: %d", a->a, a->getAasC()->c)
Depending on how you compiler does the reintpret cast the above will
either segfault or print:
A: 50, C: 50
Nothing strange in my mind, the standard says that:
[quote]
5.2.10:
3 The mapping performed by reinterpret_cast is implementation-defined.
[Note: it might, or might not, produce a representation different
from the original value. ]
4 A pointer can be explicitly converted to any integral type large
enough to hold it. The mapping function is implementation-defined
[Note: it is intended to be unsurprising to those who know the
addressing structure of the underlying machine. ]
[end quote]
My compiler didn't even give me a warning! I think it should give you
an error if you try to cast something and it doesn't know how to do the
cast.
But the above conversion is well-defined according to the standard,
and the compilers do know how to do the cast.
In the same section of the standard, we have:
[quote]
7 A pointer to an object can be explicitly converted to a pointer to
an object of different type. Except that converting an rvalue
of type "pointer to T1" to the type "pointer to T2" (where T1 and T2
are object types and where the alignment requirements of T2 are no
stricter than those of T1) and back to its original type yields the
original pointer value, the result of such a pointer conversion is
unspecified.
[end quote]
So you see the conversion itself is valid, but the result depends on
the definitions of A and C. That is, who wrote such conversion will be
responsible for the surprising or unsurprising result. :-)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]