tags:

views:

107

answers:

2

Guys I've asked few days ago a question and didn't have really time to check it and think about it, but now I've tried one of the solutions and I can't understand why does it work? I mean why destructor is called at the end of line like this:

#include "stdafx.h"
#include "coutn.h"
#define  coutn coutn()
int _tmain(int argc, _TCHAR* argv[])
{
    coutn << "Line one " << 1;//WHY DTOR IS CALLED HERE
    coutn << "Line two " << " and some text.";
    return 0;
}

I assume that it has something to do with lifetime of an object but I'm not sure what and how. As I think of it there are two unnamed objects created but they do not go out of scope so I can't understand for what reason is dtor called.
Thank you.

+7  A: 

coutn() create a temporary object, which will be destroyed at the next sequence point (the end of the line in this case).

Peter Alexander
@Peter but why is this object temporary? And even though I write something like this: auto tmp = coutn << "Line one" << 1; it's still working.
There is nothing we can do
@A-ha: When the compiler detects that an object will (and can) **not** be longer used, it calls the destructor. Usually this happens at the end of blocks or, as Peter stated, sequence points. In the case you describe, if `tmp` is no used afterwards, the compiler might just optimize things and decide it is a temporary object.
ereOn
@A-ha: Simple answer: because the standard says so §12.2/1 *Temporaries are created in various contexts... returning an r-value* When you return an object from a function (as compared to a reference) a temporary object is created to hold the return value inside the function so that the caller can read it. Now, the compiler can optimize the creation of that temporary if it is used to initialize an object of the same type in the caller function in which case it will not be destroyed, but if it is created it must be destroyed at the next sequence point.
David Rodríguez - dribeas
@A-ha: When you do the `auto tmp = ...` thing, you are creating a *copy* of the temporary object. The temporary is copied into `tmp` and then the temporary is destroyed. In that case, you'll get another destructor call when `tmp` goes out of scope.
Peter Alexander
@Peter Alexander, A-ha: If you do `auto tmp = ...` chances are that the compiler will elide the creation of the temporary (by placing the `tmp` variable in the location of memory where the temporary would be created, and then not destroying anything at the next sequence point. That is, the compiler can manage in many cases to avoid the temporary and the copy construction by having both the temporary and the destination variable share the same memory. The net effect is that the function will initialize the `tmp` variable, the copy will not be performed, and only one object will be present.
David Rodríguez - dribeas
@David: That's true, but he said that it still happened, so I'm guessing the compiler didn't manage to elide the copy.
Peter Alexander
@Peter: Destruction of temporaries has absolutely nothing to do with sequence points. A temporary is destroyed when evaluation of the full-expression that contains the rvalue, whose evaluation triggered the creation of the temporary, is completed.
FredOverflow
+3  A: 

The standard says:

Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created.

A full-expression is an expression that is not a subexpression of another expression

FredOverflow