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