This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Unexpected C++ program result


On 7 February 2012 17:21, Mattia Jona-Lasinio wrote:
>
> The program wants to test the C++ feature that pointers to a derived
> class can be assigned consistently to a pointer variable to the base
> class. This does not seem to be the case with g++. Is it the intended
> behavior?

The program has undefined behaviour.

"In the first alternative (delete object), the value of the operand of
delete may be a null pointer
value, a pointer to a non-array object created by a previous
new-expression, or a pointer to a subobject (1.8) representing a base
class of such an object (Clause 10). If not, the behavior is
undefined. In the second alternative (delete array), the value of the
operand of delete may be a null pointer value or a pointer value that
resulted from a previous array new-expression. If not, the behavior is
undefined."

N.B. 'delete array' cannot be used for pointers to base class.

"In the first alternative (delete object), if the static type of the
object to be deleted is different from its dynamic type, the static
type shall be a base class of the dynamic type of the object to be
deleted and the static type shall have a virtual destructor or the
behavior is undefined. In the second alternative (delete array) if the
dynamic type of the object to be deleted differs from its static type,
the behavior is undefined."

N.B. A virtual destructor does not help for the delete array case.

You should not upcast a pointer to an array - you can't access array
elements and you can't delete the array - don't do it.

If the derived type has a different size to the base type then pointer
arithmetic won't work and you can't access the array elements:

#include <iostream>
struct B { int i; B() : i(1) { } };
struct D : B { int j; D() : j(2) { }};

int main()
{
    B* b = new D[2];
    std::cout << b[1].i << std::endl;
}

This prints 2 even though B::i always has the value 1.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]