Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is parameter binding sequenced after argument evaluation?

Suppose I have the following function:

void foo(std::vector<int> vec, int n);

If I call the function like this:

std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
foo(std::move(numbers), numbers[0]);

Are all the arguments completely evaluated before being bound to their parameters? In that case, the std::move is harmless, because it simply yields an xvalue referring to numbers. Or can each individual argument immediately be bound to its parameter as soon as it is evaluated? In that case, numbers[0] could cause undefined behavior, because numbers could already have been moved into vec.

like image 523
fredoverflow Avatar asked Aug 29 '11 11:08

fredoverflow


People also ask

What is the relationship between parameter and argument?

Note the difference between parameters and arguments: Function parameters are the names listed in the function's definition. Function arguments are the real values passed to the function. Parameters are initialized to the values of the arguments supplied.

Do you pass parameters or arguments?

Arguments are passed by value; that is, when a function is called, the parameter receives a copy of the argument's value, not its address. This rule applies to all scalar values, structures, and unions passed as arguments. Modifying a parameter does not modify the corresponding argument passed by the function call.

What happens when an argument is passed by reference to a method?

When you pass an argument by reference, you pass a pointer to the value in memory. The function operates on the argument. When a function changes the value of an argument passed by reference, the original value changes. When you pass an argument by value, you pass a copy of the value in memory.

What is the difference between a parameter and an argument 4?

A parameter is a variable in the declaration of the function. An argument is the actual value of the variable that gets passed to the function.


1 Answers

On §1.9/15 we're told that:

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. (...)

And on §5.2.2/4:

(...) The initialization and destruction of each parameter occurs within the context of the calling function. (...)

I couldn't find any other relevant text in the final draft. Since this does not explicitly define a sequenced before relationship between evaluation of arguments and the initialization of the parameters, they're unsequenced and the std::move is not harmless.

A solution to this issue would be to force a sequence with a temporary variable:

std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
int num = numbers[0];
foo(std::move(numbers), num);
like image 195
R. Martinho Fernandes Avatar answered Sep 18 '22 15:09

R. Martinho Fernandes