Ruslan
Ruslan

Reputation: 19140

Is this code behavior well-defined?

Here's some C++ code:

#include <iostream>

class A
{
    int x;
    int y;
    double v;

    public:
        A(int x, int y)
            :x(x),y(y)
        {
            std::cerr << "A("<<x<<","<<y<<")\n";
        }
        ~A()
        {
            std::cerr << "~A()\n";
        }
        operator double* ()
        {
            v=1.5*x+y;
            return &v;
        }
};

void f(double* val)
{
    std::cerr << "f("<<*val<<")\n";
    *val=0.3;
}

int main()
{
    f(A(3,5));
}

I get the following as output:

A(3,5)
f(9.5)
~A()

I.e. as I'd like it to work. But I'm not sure whether destructor of A must be called after f returns. Is it guaranteed? Can the pointer returned by operator double* () somehow become invalid in the call of f?

Upvotes: 4

Views: 227

Answers (2)

Andre Kostur
Andre Kostur

Reputation: 780

The arguments to a function are evaluated before the function is invoked, and the temporaries will live to the end of the full expression that they are in. So yes, the instance of A will live to just past the end of the invocation of f.

Upvotes: 3

You are declaring an A object as an actual parameter of f, when you do that, for all effects the new object is like a local variable of f so ~A is guaranteed to be called at the end of f execution.

If f returns the address returned by operator double* () and it is used after f has returned you will be accessing to invalid memory. One way to avoid this situation is making double v static but you have to consider that, in your code, the A class created object only exits while f block is running.

Upvotes: 4

Related Questions