This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/26862] New: Non-pod data structure copied incorrectly during static initialization
- From: "e_hohenstein at yahoo dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 25 Mar 2006 02:29:01 -0000
- Subject: [Bug c++/26862] New: Non-pod data structure copied incorrectly during static initialization
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
When a structure is defined without a constructor but that contains non-pod
data, the containing structure is also non-pod. When an array of these
enclosing non-pod structures is declared as a global static array with an
initializer list, the structures appear to be constructed on the stack and
copied into place without the use of the copy constructors of the contained
non-pod members, which is illegal.
The following C++ program demonstrates the problem:
#include <iostream>
class A {
public:
A( int b ) {
a_ = reinterpret_cast< void * >( this );
b_ = b;
}
A( A const & that ) {
a_ = this;
b_ = that.b_;
}
void dump() const {
std::cout << " this = " << reinterpret_cast< const void * >( this ) <<
std::endl;
std::cout << " a_ = " << a_ << std::endl;
std::cout << " b_ = " << b_ << std::endl << std::endl;
}
private:
const void * a_;
int b_;
};
A globalA( 1 );
static const A globalAArray[] =
{
A( 11 ),
A( 22 ),
A( 33 )
};
struct ContainsA {
#if !defined( SHOW_GCC_BUG )
ContainsA( A const & a1, A const & a2 );
#endif // #if !defined( SHOW_GCC_BUG )
A a1_;
A a2_;
};
#if !defined( SHOW_GCC_BUG )
ContainsA::ContainsA( A const & a1, A const & a2 )
: a1_( a1 ),
a2_( a2 ) {
}
#endif // #if !defined( SHOW_GCC_BUG )
static const ContainsA containsAArray[] =
{
#if !defined( SHOW_GCC_BUG )
ContainsA( A( 111 ), A( 222 ) ),
ContainsA( A( 333 ), A( 444 ) ),
ContainsA( A( 555 ), A( 666 ) )
#else // #if !defined( SHOW_GCC_BUG )
{
A( 111 ),
A( 222 )
},
{
A( 333 ),
A( 444 )
},
{
A( 555 ),
A( 666 )
}
#endif // #if !defined( SHOW_GCC_BUG )
};
int main( void ) {
std::cout << "Global A:" << std::endl;
globalA.dump();
std::cout << "Local A:" << std::endl;
A localA( 3 );
localA.dump();
std::cout << "Global A Array:" << std::endl;
for ( int i = 0; i < 3; ++i ) {
globalAArray[ i ].dump();
}
std::cout << "Global ContainsA Array:" << std::endl;
for ( int i = 0; i < 3; ++i ) {
containsAArray[ i ].a1_.dump();
containsAArray[ i ].a2_.dump();
}
return 0;
}
If this program is compiled (on gcc 3.4.2) using -DSHOW_GCC_BUG and run, the
output shows that "a_ != this", which is not correct. Both constructors of the
non-pod A class assign "a_ = this". There should never be an instance of A
where "a_ != this". Inspecting the values of a_ when "a_ != this" shows that
they are similar to the value of a_ for the instance of class A created locally
(on the stack), suggesting that the instances of A or the instances of
ContainsA were created on the stack and then memcpy'd or memmov'd into place
rather than copy constructed into place. Either of these cases is invalid
because class A is non-pod and should not ever be memcpy'd.
--
Summary: Non-pod data structure copied incorrectly during static
initialization
Product: gcc
Version: 3.4.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: e_hohenstein at yahoo dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26862