Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to return a passed-in temporary value and read from it in the same statement?

I just wrote this without thinking too hard about it. It seems to work fine, but I'm not sure if it's strictly safe.

class Foo
{
    struct Buffer
    {
        char data [sizeof ("output will look like this XXXX YYYY ZZZZ")];
    };

    const char * print (const char * format = DEFUALT_FORMAT, Buffer && buf = Buffer ())
    {
        sort_of_sprintf_thing (format, buf .data, sizeof (buf.data), ...);
        return buf .data;
    }
};

std :: cout << Foo () .print ();

So I think the semantics are that the temporary Buffer will remain in existence until the whole cout statement completes. Is that right, or will it go out of scope before then, in which case this is UB?

like image 335
spraff Avatar asked Feb 02 '15 14:02

spraff


People also ask

Is it better to return value from a function or pass in a pointer in C?

You need to pass a pointer to a function when you need to modify the elements of an array. In C, you can't pass an array or return an array from a function. Answer for your second question is, in C function argument are passed by value.

What happens when a value is returned?

Nothing. The return value is simply discarded. It doesn't matter what you return, as long as you return something. (And do make sure you return something.

Is it good idea to return an address or a reference of a local variable?

The return statement should not return a pointer that has the address of a local variable ( sum ) because, as soon as the function exits, all local variables are destroyed and your pointer will be pointing to someplace in the memory that you no longer own.

Which statement is correct about pass by value?

Answer: b -> Yes pass by value creates a copy of the original variable.


1 Answers

Yes, your code is well-defined.

[class.temporary]

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

[intro.execution]

11 - [ Note: The evaluation of a full-expression can include the evaluation of subexpressions that are not lexically part of the full-expression. For example, subexpressions involved in evaluating default arguments (8.3.6) are considered to be created in the expression that calls the function, not the expression that defines the default argument. — end note ]

That doesn't mean it's particularly good, though - it would be far too easy to bind the result of Foo().print() to a char const* variable, which would on the next full-expression become a dangling pointer.

like image 149
ecatmur Avatar answered Nov 15 '22 15:11

ecatmur