This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
order of evaluation of function parameters
Is it safe to use the following construction in C/C++?
f(g(), h());
where g() is expected to be evaluated first, then h().
Do all compilers show the same behavior on all architectures?
NO! There is no guarantee what order these are carried out in. Only that both g() and h() are carried out before f().
See this: http://www.gotw.ca/gotw/056.htm
I think there's an updated C++11 version of that, I'll have a look.
Edit: C++11 version http://herbsutter.com/gotw/_102/
Edit 2: If you really want to know what specific compilers do, try this: http://www.agner.org/optimize/calling_conventions.pdf
Section 7 (page 16) may be relevant, though it's a bit over my head, but for instance __cdecl calling convention means arguments are passed from right to left (at least stored that way), whereas for __fastcall "The first two DWORD or smaller arguments are passed in ECX and EDX registers; all other arguments are passed right to left." (http://msdn.microsoft.com/en-us/library/6xa169sk%28v=vs.71%29.aspx)
So it does vary for different compilers.
Much later edit: It turns out that for constructors using the initializer list syntax (curly braces {}), order of evaluation is guaranteed (even if it is a call to a constructor that does not take a std::initializer_list. See this question.
See 1.9 Program execution:
Certain other aspects and operations of the abstract machine are described in this International Standard as
unspecified (for example, order of evaluation of arguments to a function). Where possible, this International
Standard defines a set of allowable behaviors.
and 8.3.6 Default arguments, 9:
[...] Default arguments are evaluated each time the function is called. The order of evaluation of function
arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument,
even if they are not evaluated. [...]
No, it's not safe - if you need a guaranteed order of evaluation, e.g. because of side effects, then you will need to do something like this:
foo = g();
bar = h();
f(foo, bar);
No, the order of evaluation of arguments with respect to each other is unspecified. The only guarantee that you have is that they will not be executed concurrently with each other.
No.
The standard don't define the order of evaluation in that case, and each compiler may do whatever it wants.
I think that most of them (and specially gcc) evaluate the rightest first.
Related
If we have three functions (foo, bar, and baz) that are composed like so...
foo(bar(), baz())
Is there any guarantee by the C++ standard that bar will be evaluated before baz?
No, there's no such guarantee. It's unspecified according to the C++ standard.
Bjarne Stroustrup also says it explicitly in "The C++ Programming Language" 3rd edition section 6.2.2, with some reasoning:
Better code can be generated in the
absence of restrictions on expression
evaluation order
Although technically this refers to an earlier part of the same section which says that the order of evaluation of parts of an expression is also unspecified, i.e.
int x = f(2) + g(3); // unspecified whether f() or g() is called first
From [5.2.2] Function call,
The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered.
Therefore, there is no guarantee that bar() will run before baz(), only that bar() and baz() will be called before foo.
Also note from [5] Expressions that:
except where noted [e.g. special rules for && and ||], the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.
so even if you were asking whether bar() will run before baz() in foo(bar() + baz()), the order is still unspecified.
There's no specified order for bar() and baz() - the only thing the Standard says is that they will both be evaluated before foo() is called. From the C++ Standard, section 5.2.2/8:
The order of evaluation of arguments
is unspecified.
C++17 specifies evaluation order for operators that was unspecified until C++17. See the question What are the evaluation order guarantees introduced by C++17? But note your expression
foo(bar(), baz())
has still unspecified evaluation order.
In C++11, the relevant text can be found in 8.3.6 Default arguments/9 (Emphasis mine)
Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated.
The same verbiage is used by C++14 standard as well, and is found under the same section.
As others have already pointed out, the standard does not give any guidance on order of evaluation for this particular scenario. This order of evaluation is then left to the compiler, and the compiler might have a guarantee.
It's important to remember that the C++ standard is really a language to instruct a compiler on constructing assembly/machine code. The standard is only one part of the equation. Where the standard is ambiguous or is specifically implementation defined you should turn to the compiler and understand how it translates C++ instructions into true machine language.
So, if order of evaluation is a requirement, or at least important, and being cross-compiler compatible is not a requirement, investigate how your compiler will ultimately piece this together, your answer could ultimate lie there. Note that the compiler could change it's methodology in the future
I am new to C++ and I am writing pseudo code here:
void fn(a) {}
fn(b)
It is correct to assume that in the function body fn what happens is this assignment
`a = b`
I know we can pass the reference/pointer instead of just the value. I get it. But at its core, it still does this assignment of parameter = argument right?
I would like to know:
if there is any official term for this?
when exactly does this assignment happen and what exactly makes this happen? is it the compiler?
if there is any official term for this?
The official semantics of a function call are discussed in the “Function call” section of the C standard. There is no term specifically for the assignments of values to parameters.
C++ 2017 draft N4659 8.2.2 “Function call” [expr.call] 4 says:
When a function is called, each parameter (11.3.5) shall be initialized (11.6, 15.8, 15.1) with its corresponding argument…
when exactly does this assignment happen and what exactly makes this happen? is it the compiler?
It happens when a function is called. The compiler is responsible for generating code that produces a program that performs the semantics of the source code (as defined by the C++ standard).
The C++ standard describes an execution environment, the results of various types of statements and the results of various types of expressions. A compiler is only required to produce code that, when,run, produces results as-if it were run on that described execution environment.
In terms of your actual question, that means that a function call in source code does not necessarily translate into any sort of call or jump instruction when run on actual hardware.
For example, given the function:
int sqr(int x, inty)
{
return x*y;
}
a compiler might well simply compute such a result in-place and not perform any sort of parameter passing. But whether you can actually count on that behavior is a detail left up to the compiler implementor.
All that being said, on actual hardware and without inlining, a function call's parameters are very much like any other variable initialization (think copy rather than assign). The exact details (such as order of parameter evaluation) are left up to each implementation.
If we have three functions (foo, bar, and baz) that are composed like so...
foo(bar(), baz())
Is there any guarantee by the C++ standard that bar will be evaluated before baz?
No, there's no such guarantee. It's unspecified according to the C++ standard.
Bjarne Stroustrup also says it explicitly in "The C++ Programming Language" 3rd edition section 6.2.2, with some reasoning:
Better code can be generated in the
absence of restrictions on expression
evaluation order
Although technically this refers to an earlier part of the same section which says that the order of evaluation of parts of an expression is also unspecified, i.e.
int x = f(2) + g(3); // unspecified whether f() or g() is called first
From [5.2.2] Function call,
The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered.
Therefore, there is no guarantee that bar() will run before baz(), only that bar() and baz() will be called before foo.
Also note from [5] Expressions that:
except where noted [e.g. special rules for && and ||], the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.
so even if you were asking whether bar() will run before baz() in foo(bar() + baz()), the order is still unspecified.
There's no specified order for bar() and baz() - the only thing the Standard says is that they will both be evaluated before foo() is called. From the C++ Standard, section 5.2.2/8:
The order of evaluation of arguments
is unspecified.
C++17 specifies evaluation order for operators that was unspecified until C++17. See the question What are the evaluation order guarantees introduced by C++17? But note your expression
foo(bar(), baz())
has still unspecified evaluation order.
In C++11, the relevant text can be found in 8.3.6 Default arguments/9 (Emphasis mine)
Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated.
The same verbiage is used by C++14 standard as well, and is found under the same section.
As others have already pointed out, the standard does not give any guidance on order of evaluation for this particular scenario. This order of evaluation is then left to the compiler, and the compiler might have a guarantee.
It's important to remember that the C++ standard is really a language to instruct a compiler on constructing assembly/machine code. The standard is only one part of the equation. Where the standard is ambiguous or is specifically implementation defined you should turn to the compiler and understand how it translates C++ instructions into true machine language.
So, if order of evaluation is a requirement, or at least important, and being cross-compiler compatible is not a requirement, investigate how your compiler will ultimately piece this together, your answer could ultimate lie there. Note that the compiler could change it's methodology in the future
If we have three functions (foo, bar, and baz) that are composed like so...
foo(bar(), baz())
Is there any guarantee by the C++ standard that bar will be evaluated before baz?
No, there's no such guarantee. It's unspecified according to the C++ standard.
Bjarne Stroustrup also says it explicitly in "The C++ Programming Language" 3rd edition section 6.2.2, with some reasoning:
Better code can be generated in the
absence of restrictions on expression
evaluation order
Although technically this refers to an earlier part of the same section which says that the order of evaluation of parts of an expression is also unspecified, i.e.
int x = f(2) + g(3); // unspecified whether f() or g() is called first
From [5.2.2] Function call,
The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered.
Therefore, there is no guarantee that bar() will run before baz(), only that bar() and baz() will be called before foo.
Also note from [5] Expressions that:
except where noted [e.g. special rules for && and ||], the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.
so even if you were asking whether bar() will run before baz() in foo(bar() + baz()), the order is still unspecified.
There's no specified order for bar() and baz() - the only thing the Standard says is that they will both be evaluated before foo() is called. From the C++ Standard, section 5.2.2/8:
The order of evaluation of arguments
is unspecified.
C++17 specifies evaluation order for operators that was unspecified until C++17. See the question What are the evaluation order guarantees introduced by C++17? But note your expression
foo(bar(), baz())
has still unspecified evaluation order.
In C++11, the relevant text can be found in 8.3.6 Default arguments/9 (Emphasis mine)
Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated.
The same verbiage is used by C++14 standard as well, and is found under the same section.
As others have already pointed out, the standard does not give any guidance on order of evaluation for this particular scenario. This order of evaluation is then left to the compiler, and the compiler might have a guarantee.
It's important to remember that the C++ standard is really a language to instruct a compiler on constructing assembly/machine code. The standard is only one part of the equation. Where the standard is ambiguous or is specifically implementation defined you should turn to the compiler and understand how it translates C++ instructions into true machine language.
So, if order of evaluation is a requirement, or at least important, and being cross-compiler compatible is not a requirement, investigate how your compiler will ultimately piece this together, your answer could ultimate lie there. Note that the compiler could change it's methodology in the future
If we have three functions (foo, bar, and baz) that are composed like so...
foo(bar(), baz())
Is there any guarantee by the C++ standard that bar will be evaluated before baz?
No, there's no such guarantee. It's unspecified according to the C++ standard.
Bjarne Stroustrup also says it explicitly in "The C++ Programming Language" 3rd edition section 6.2.2, with some reasoning:
Better code can be generated in the
absence of restrictions on expression
evaluation order
Although technically this refers to an earlier part of the same section which says that the order of evaluation of parts of an expression is also unspecified, i.e.
int x = f(2) + g(3); // unspecified whether f() or g() is called first
From [5.2.2] Function call,
The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered.
Therefore, there is no guarantee that bar() will run before baz(), only that bar() and baz() will be called before foo.
Also note from [5] Expressions that:
except where noted [e.g. special rules for && and ||], the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.
so even if you were asking whether bar() will run before baz() in foo(bar() + baz()), the order is still unspecified.
There's no specified order for bar() and baz() - the only thing the Standard says is that they will both be evaluated before foo() is called. From the C++ Standard, section 5.2.2/8:
The order of evaluation of arguments
is unspecified.
C++17 specifies evaluation order for operators that was unspecified until C++17. See the question What are the evaluation order guarantees introduced by C++17? But note your expression
foo(bar(), baz())
has still unspecified evaluation order.
In C++11, the relevant text can be found in 8.3.6 Default arguments/9 (Emphasis mine)
Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated.
The same verbiage is used by C++14 standard as well, and is found under the same section.
As others have already pointed out, the standard does not give any guidance on order of evaluation for this particular scenario. This order of evaluation is then left to the compiler, and the compiler might have a guarantee.
It's important to remember that the C++ standard is really a language to instruct a compiler on constructing assembly/machine code. The standard is only one part of the equation. Where the standard is ambiguous or is specifically implementation defined you should turn to the compiler and understand how it translates C++ instructions into true machine language.
So, if order of evaluation is a requirement, or at least important, and being cross-compiler compatible is not a requirement, investigate how your compiler will ultimately piece this together, your answer could ultimate lie there. Note that the compiler could change it's methodology in the future