Bug 13064 - getting address of a virtual base before its construction causes a crash
Summary: getting address of a virtual base before its construction causes a crash
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.3.2
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-11-16 00:27 UTC by Joseph Artsimovich
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph Artsimovich 2003-11-16 00:27:03 UTC
The following program compiles but crashes at runtime.

=== test.cpp ===
struct A {};

struct B : virtual public A
{
        B(A*) {}
};

struct C
{
        C() : b(&b) {}
        B b;
};

int main()
{
        new C;
}
=========

Command line:
g++ -Wall test.cpp
Comment 1 Andrew Pinski 2003-11-16 00:51:25 UTC
The problem is that the lifetime of b has not been started yet so you get a crash (optimizing will 
remove the crash only because of inlining) so the behavior is undefined.

From the C++ standard, 2.8 [basic.life]:
The liftime of an object of type T begins when:
— storage with the proper alignment and size for type T is obtained and  (this is true but)
— if T is a class type with a non-trrivial constructor (12.1), the constructor has completed (this is 
not so the behavior is undefined and could cause a crash).

From 12.1.5 (Constructors):
A constuctor is trival if it is an implictly-declared default constructor (this is not true in this 
example)  and if ....
Comment 2 Joseph Artsimovich 2003-11-16 01:58:55 UTC
Does the standard say I can't take the address of an object that has already 
been allocated but not yet constructed? 
 
Comment 3 Andrew Pinski 2003-11-16 03:08:53 UTC
Yes 12.7.2 :
To explicitly or implicitly convert a pointer (an lvalue) refering to an object of class X to a pointer 
(reference) to a direct or indirect base class B of X, the construction of X and the construction of all 
of its direct or indirect bases that directly or indirectly derive from B shall have started and the 
destruction of these classes shall not have completed, otherwise the conversion results in 
undefined behavior.

In your example the construtor of b have not started yet.