TITLE: Destruction of temporaries


RESPONSE: fritz@mtl.mit.edu (Frederick Herrmann), 21 Sept 93
	  MIT Microsystems Technology Laboratories

I was surprised by the order of construction and destruction of objects in the
following program:

    #include <iostream.h>

    class B {
    public:
      B();
      B(const B&) ;
      ~B();
    };

    B::B()		{ cout << "Default construct this=" << this << endl; }
    B::B(const B&)	{ cout << "Copy construct this=" << this << endl; }
    B::~B()		{ cout << "Destruct this=" << this << endl; }

    void f( B) {}

    int main( int, char**)
    {
      B b;

      f(b);
      f(b);

      return 0;
    }

g++ (2.4.5) does what I expect:

    Default construct this=0xf7fff8a8
    Copy construct this=0xf7fff8a0
    Destruct this=0xf7fff8a0
    Copy construct this=0xf7fff898
    Destruct this=0xf7fff898
    Destruct this=0xf7fff8a8

The copy constructor is called when entering f(B), and the destructor is
called upon return.

Sun C++ 3.0.1 (cfront-based) does things a little differently:

    Default construct this=0xf7fff8b3
    Copy construct this=0xf7fff8ab
    Copy construct this=0xf7fff8aa
    Destruct this=0xf7fff8aa
    Destruct this=0xf7fff8ab
    Destruct this=0xf7fff8b3

The arguments passed to f are not destructed until we return from main.

ARM 12.4 says that destructors are invoked when auto or temporary objects go
out of scope.
ARM 12.2 gives compilers pretty broad license to destruct temporaries whenever
they please.

Which rules apply here?  Are function arguments to be considered temporaries
in the scope of the caller, or automatics in the scope of the callee?

If temporaries, then cfront is free to do what it likes.
If automatics, then cfront is destructing the arguments too late.


[ I always assumed that the order of construction/destruction would
  occur as g++ above (fortunately I do not write code that depends
  on it!

  Jam, do you have any information on this?

  -adc ]
