kent@humu.nosc.mil (Kent K. Kuriyama) (03/25/91)
There seems to be a bug in the code that Turbo C++ 1.00 generates.
In the following program the destructor routine should only be called
once.
------------
# include <stdio.h>
class A {
protected:
int i;
public:
A();
~A();
};
A::A()
{
printf("Constructor called\n");
}
A::~A()
{
printf("Destructor called\n");
}
void sub(A a)
{
printf("in sub\n");
}
void main()
{
A a;
printf("before call\n");
sub(a);
printf("after call\n");
}
------------
When this program is executed:
------------
Constructor called
before call
in sub
after call
Destructor called
Destructor called
------------
Am I wrong to think that the destructor should only be called once?
Kent Kuriyama Voice (808) 257-1618
Naval Ocean Systems Center FAX (808) 257-1685
Hawaii Laboratory Box 997, Code 531
kent@nosc.mil Kailua, HI 96734 wmm@world.std.com (William M Miller) (03/25/91)
kent@humu.nosc.mil (Kent K. Kuriyama) writes: > void main() > { > A a; > > printf("before call\n"); > sub(a); > printf("after call\n"); > } > ------------ > > When this program is executed: > > ------------ > Constructor called > before call > in sub > after call > Destructor called > Destructor called > ------------ > > Am I wrong to think that the destructor should only be called once? Yes. C++ has, by default, the call-by-value semantics of C. When you called "sub(a)", an object was created to hold the copy of "a" that was actually passed to "sub()." Since you didn't provide a constructor that could be used for this purpose (it's called a "copy constructor" and is declared as "A::A(const A&)"), the compiler generated a default one for you that just did a bit-for-bit copy. Naturally, the default one didn't have a printf() call in it, so its execution didn't show up in your output. Of the two destructors, one is for the copy passed to "sub()," the other is for "a." -- William M. Miller, Glockenspiel, Ltd. wmm@world.std.com
horstman@mathcs.sjsu.edu (Cay Horstmann) (03/26/91)
In article <546@humu.NOSC.Mil> you write: >There seems to be a bug in the code that Turbo C++ 1.00 generates. >In the following program the destructor routine should only be called >once. > >------------ ># include <stdio.h> > >class A { > protected: > int i; > public: > A(); > ~A(); >}; > >A::A() >{ > printf("Constructor called\n"); >} > >A::~A() >{ > printf("Destructor called\n"); >} > >void sub(A a) >{ > printf("in sub\n"); >} > >void main() >{ > A a; > > printf("before call\n"); > sub(a); > printf("after call\n"); >} >------------ > >When this program is executed: > >------------ >Constructor called >before call >in sub >after call >Destructor called >Destructor called >------------ > You are wrong. You didn't supply a copy constructor for A (i.e. no A(const A&)). That made the argument in sub constructed with a bitwise copy but destroyed with the ~A(). The only funny thing is that Turbo routinely translates a function call sub(a) into A temp = a; sub( temp ) and changes void sub( A a ) into void sub( A& a ). It beats me why they do it, but they do, and that is why the destructor is called both times after sub exits. I ran into some cases when the destructor didn't get called enough, but I have a hard time reproducing it in a small and short program. If anyone has one, let me know! Cay