Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Visual Studio completely standard-conformant regarding that temporaries should be destroyed at the end of the expression?

As far as I know, temporaries should be destroyed at the end of the full expression. However, for this code snippet (godbolt), this is not true for Visual Studio:

#include <cstdio>

struct Foo {
    Foo() = default;
    Foo(const Foo &) {}
    ~Foo() {
        std::printf("~Foo()\n");
    }
};

int foo(Foo f) {
    return 0;
}

void bar(int) {
    std::printf("bar\n");
}

int main() {
    bar(foo(Foo()));
}

This code should print (because the destructor of the Foo() temporary should run after bar returned):

bar
~Foo

However, with MSVC, the code prints:

~Foo
bar

Is this behavior allowed?

like image 689
geza Avatar asked Nov 22 '25 04:11

geza


1 Answers

In this code, Foo() doesn't create a temporary object. It is a prvalue that is used to directly construct the parameter f. See [dcl.init.general]/16.6.1

The lifetime of a function parameter is governed by [expr.call]/6, which states that

[...] It is implementation-defined whether a parameter is destroyed when the function in which it is defined exits ([stmt.return], [except.ctor], [expr.await]) or at the end of the enclosing full-expression; parameters are always destroyed in the reverse order of their construction. The initialization and destruction of each parameter occurs within the context of the full-expression ([intro.execution]) where the function call appears.
[Example 2: ...]

The parameter f can be destroyed either before or after the body of bar is executed. They're both valid options for the implementation.

like image 117
Brian Bi Avatar answered Nov 23 '25 21:11

Brian Bi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!