When calling C/C++ function within another function, why do they stack? Is there a way to fix it? [duplicate] - c++

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

Related

Function operation order in C++ [duplicate]

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

undefined behavior when passing argument in C++ [duplicate]

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

X().Y(Z()) and the order of evaluation in standard

Can somebody quote the corresponding paragraph of the C++ standard that says that the order of the std::string construction and foo() call is unspecified in the following case:
std::string().append(foo());
I know that there's 5.2.2.8 but it states about function arguments, not several function calls between the same sequence points:
The order of evaluation of function arguments is unspecified
It was widely believed that leaving the order of expression evaluation undefined led to more optimizations. It was probably true 10 and 20 years ago, but it does not appear to be so any more. Data to that effect was presented to the committee, but I don't know if it is published anywhere.
5/4 [expr]:
Except where noted, 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
Because operators are functions, this means string() will be constructued either before or after foo().
Also see: Order of function call
"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.
Also see: Order of evaluation in C++ function parameters

C/C++ - evaluation of the arguments in a function call [duplicate]

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.

Order of evaluation in C++ function parameters

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