3

Does standard C++11 guarantee that all 3 temporary objects have been created before the beginning performe the function?

Even if temporary object passed as:

  1. object
  2. rvalue-reference
  3. passed only member of temporary object

http://ideone.com/EV0hSP

#include <iostream>
using namespace std;

struct T { 
    T() { std::cout << "T created \n"; }
    int val = 0;
    ~T() { std::cout << "T destroyed \n"; }
};

void function(T t_obj, T &&t, int &&val) {
    std::cout << "func-start \n";
    std::cout << t_obj.val << ", " << t.val << ", " << val << std::endl;
    std::cout << "func-end \n";
}

int main() {
    
    function(T(), T(), T().val);
    
    return 0;
}

Output:

T created 
T created 
T created 
func-start 
0, 0, 0
func-end 
T destroyed 
T destroyed 
T destroyed 

Working Draft, Standard for Programming Language C++ 2016-07-12: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf

§ 5.2.2 Function call

§ 5.2.2

1 A function call is a postfix expression followed by parentheses containing a possibly empty, comma-separated list of initializer-clauses which constitute the arguments to the function.

But can be any of T created after func-start?

Or is there any way to pass arguments as g/r/l/x/pr-value so that the function started before the temporary object be created?

enter image description here

Community
  • 1
  • 1
Alex
  • 12,578
  • 15
  • 99
  • 195
  • I don't understand the question. How could a function be of any use whatsoever if, at the time its body began executing, its arguments didn't yet exist? – underscore_d Aug 15 '16 at 12:22
  • @underscore_d In C++ it can't be what is clearly described in the standard. But if it were not described in the standard, then: **1.** `function()` can be inlined. **2.** Object can be constructed at first usage of this object, even after some code from function - bacause the compiler can reorder any operation if it does not change Observable behaviour (hasn't in/output, memory-fences, ...) - **§ 1.9 Program execution 1, 5, 8**. Quote: "the compiler may freely reorder instructions and operations however it likes." http://stackoverflow.com/questions/30606924/can-function-calls-be-reordered – Alex Aug 15 '16 at 12:50
  • Right, #2 helps me to understand and makes that a good point, which seems to be ruled out by the requirement for sequencing. I'm still waiting for C++ to gain a native syntax for lazily initialised objects... About #1, I'm sure it could still be inlined, right? just the compiler would have to create the 3 arguments first (indeterminately sequenced among themselves) and save these to use in the inlined body. – underscore_d Aug 15 '16 at 12:52

2 Answers2

11

[intro.execution]/16:

When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function.

T.C.
  • 133,968
  • 17
  • 288
  • 421
7

From [expr.call]/8 we have

[ Note: The evaluations of the postfix expression and of the arguments are all unsequenced relative to one another. All side effects of argument evaluations are sequenced before the function is entered (see 1.9). —end note ]

This means that all parameters are constructed before the function is entered.

Consequently this also guarantees that all parameters are destroyed after the function exits.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402