[gnu.g++.bug] Private constructor/destructor bug

Graeme.Dixon%newcastle.ac.uk@NSS.CS.UCL.AC.UK (Graeme Dixon) (04/11/89)

Even though a class contains private constructors and destructors, g++
allows instances of the class to be declared. The following program
illustrates the bug:

#include <stream.h>

class A
{
friend class B;

    int no_refs;

    int inc_ref_count() { return ++no_refs; }
    int dec_ref_count() { return --no_refs; }

    A() { cout << "A::A\n"; }
    ~A() { cout << "A::~A\n"; }

public:
    int get_ref_count() { return no_refs; }
};

class B
{
    A *ptr;

public:
    B()  { cout << "B::B\n";
	   ptr = (A *) 0; }
    ~B() { cout << "B::~B\n";
	   if (ptr && ptr->dec_ref_count() == 0) delete ptr; }

    void operator=(A* a) { if (ptr && ptr->dec_ref_count() == 0)
			       delete ptr;
			   ptr = a;
			   ptr->inc_ref_count(); }
    A* operator->() { return ptr; }
};

main()
{
    // this is okay...
    B b;

    b = new A;

    cout << b->get_ref_count() << "\n";

    // ...until here which shouldn't compile

    A a;     // the constructor for A isn't called
	     // but the destructor is when the scope ends

    cout << a.get_ref_count() << "\n";  // returns an incorrect value

    A *a1 = new A; // constructor called

    cout << a1->get_ref_count() << "\n"; // value returned okay

    delete a1;
}

Using g++ version 1.34.0 on a Sun 3/60M (OS 4.0.1) the above program
(compiled using g++ -o cons_bug cons_bug.cc) produces:

B::B
A::A
1
47412
A::A
0
A::~A
A::~A
B::~B
A::~A

Graeme Dixon -
  Computing Laboratory, University of Newcastle upon Tyne, UK

JANET = Graeme.Dixon@uk.ac.newcastle
ARPA  = Graeme.Dixon@newcastle.ac.uk
UUCP  = ...!ukc!newcastle.ac.uk!Graeme.Dixon
PHONE = +44 91 222 8067 

PS.
  Thanks for the overloaded delete bug fix...