Do functions compute before being called?
So I'm writing a simple program to calculate the standard deviation of a 1D array of integers. Main starts off with a function for the user to input the values of the array. Then the standard deviation function is called.
In the function for the standard deviation I include:
cout << "hello" << av << "hello" << endl;
to test if the average for the array values was correct.
Everything is normal, except for the fact that the line above is executed immediately after entry of the final array element, before I call the function, and before the first cout statement after array input. The relevant code was:
input_array(a,n);
cout << "The standard deviation of a's array elements is: \n\n";
cout << standard_deviation(a,n) << endl;
So the result in console was something like:
Input Array: 5 7 9
hello7hello
The standard deviation of a's array elements is: 1.63299
How come this happens?
KingG
Re: Do functions compute before being called?
Are you absolutely positive that you're using cout for all output? If you put some output on cout and some on cerr, it may not appear in the expected order.
Re: Do functions compute before being called?
Post real code. Your question is hard to follow and other than saying code executes sequentially, impossible to answer without seeing the code.
Re: Do functions compute before being called?
I don't understand either. Please post a minimal, fully compiling example.
Re: Do functions compute before being called?
My guess is that the compiler sees that your standard deviation function must be called before the (cout) string announcing the standard deviation can be printed.
Consequently, immediately after acquiring the int array, it calls the standard deviation function in order to complete the standard deviation announcement string.
However, during the course of that function execution, the function-internal cout is executed. Unlike the standard deviation announcement string, the internal cout is not dependent upon any other value and so may be printed immediately.
So the order of steps is
1. get the int array to work with.
( int values are displayed )
2. execute the standard deviation function
( display the function-resident cout giving the average value as it occurs, w/o hesitation)
3. display the now-complete standard deviation string.
In short, I don't think this is an example of a quantum physics thingy reversing cause-and-effect: functions do not compute before being called, but at the compiler's discretion, functions may be called before their appearance in a program.
I think you can verify this by setting a breakpoint at that point in your program and wait for the break. When it occurs, click on Debug/windows/disassembly and read the code.
Re: Do functions compute before being called?
Sorry for the confusion guys, I actually deleted it so had to rewrite - will be a little different to what I've already mentioned above, does the same thing though. Here's the code:
Code:
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
void inputarray(int a[]);
float sd(int a[]);
int main()
{
int a[3];
inputarray(a);
cout << "The standard deviation of these numbers is " << sd(a) << endl;
int k;
cout << "Press any key then enter to leave...";
cin >> k;
return 0;
}
void inputarray(int a[])
{
for(int i=0; i<3; i++)
{
cout << "Input array element " << i << ": ";
cin >> a[i];
}
}
float sd(int a[])
{
int total=0;
for (int i=0; i<3 ; i++)
total+=a[i];
float av=static_cast<float>(total)/3;
cout << av << endl; //THIS IS WHAT OCCURS IN WEIRD ORDER!!!
float tot2=0;
for (int i=0; i<3 ; i++)
{
float k=a[i];
tot2+=(k-av)*(k-av);
}
return sqrt(tot2/3.0);
}
The output is:
Input array element 0: 5
Input array element 1: 7
Input array element 2: 9
7
The standard deviation of these numbers is 1.63299.
Lindley, I haven't used cerr before.
Re: Do functions compute before being called?
As mentioned in my earlier post immediately prior to your listing above, I don't think there's anything unusual about the ordering of the strings.
Certainly I may be mistaken, but I believe this ordering is what is to be expected given the code.
Re: Do functions compute before being called?
The output is correct ...
I'm not sure what your question is. You call sd(a) which prints
the average (7 in your example)
EDIT:
I see what you are talking about
There is no guarentee that sd(a) will be called after the initial part of the
write statement. You need to break it up:
Code:
cout << "The standard deviation of these numbers is ";
cout << sd(a) << endl;
Re: Do functions compute before being called?
What you are encountering is the fact that the order in which arguments to a function are evaluated is undefined. The expression:
cout << "The standard deviation of these numbers is " << sd(a) << endl;
is a series of function calls of the form
ostream& operator<<(ostream&, const T &value);
In particular, the expression on the left in one case is:
cout << "The standard deviation of these numbers is " (this has the type ostream)
and the expression on the right is
sd(a) (this has type float).
The order in which these two expressions are evaluated is undefined.
See here for some more details:
http://www.cppreference.com/wiki/lan...tor_precedence
Re: Do functions compute before being called?
I was going to explain further, but Lindley beat me to it ... here
is what I had written:
1. Your cout statement is the same as:
Code:
operator << (cout,"The standard deviation of these numbers is ").operator << (sd(a));
2. Consider this example:
Code:
int foo(int x)
{
cout << "x = " << x << "\n";
return x;
}
void bar(int x , int y) {}
// ..
bar ( foo(1) , foo(2) );
There is no guarentee that foo(1) will be called before foo2()
I believe the cout example is basically the same as this one, in that
sd(a) can be executed first.
Re: Do functions compute before being called?
If ostream really does have << as a member method, then there's no question that sd(a) would need to be evaluated first. I was assuming that all of the << overloads were free functions.
Re: Do functions compute before being called?
Thanks for all replies guys, but my understanding of your replies are limited so I will only reply to a few for now...
Quote:
Originally Posted by
Philip Nicoletti
There is no guarentee that sd(a) will be called after the initial part of the
write statement. You need to break it up:
Code:
cout << "The standard deviation of these numbers is ";
cout << sd(a) << endl;
I tried this and the output appears as expected. So I'm gathering from this that it is good practice to break up chain cout statements which contain function calls. Good good.
Now, you say there is no guarantee that sd(a) will be called after the initial part of the write statement. So is it possible that even if my sd(a) had no cout statement, the output COULD be this?:
"
Input array element 0: 5
Input array element 1: 7
Input array element 2: 9
1.63299
The standard deviation of these numbers is
"
Because I was under the impression that whatever a function RETURNED, would occur only when/where it was called (i.e. in the right place, as it did in this case before). Is this wrong? Are you saying that my sd(a) value of 1.63299 only turned up after the "The standard deviation of these numbers is" sentence by fluke?
And seeing as the cout statement in my sd(a) was not a 'return' as such, I wasn't so surprised when it turned up in a weird place.
Cout statements in int/float/double functions aren't usual/proper, I guess. Can someone confirm this for me? It was just a result of my tinkering about, no idea if it is ever done for any reason. I am under the impression that cout are usually only included in void functions.
Re: Do functions compute before being called?
No ... the RETURN value of sd(a) will always be printed in the
correct location.
Re: Do functions compute before being called?
Quote:
Originally Posted by
KingGhidorah
So I'm gathering from this that it is good practice to break up chain cout statements which contain function calls.
IMO, that's a wrong conclusion.
Quote:
Originally Posted by
KingGhidorah
Now, you say there is no guarantee that sd(a) will be called after the initial part of the write statement. So is it possible that even if my sd(a) had no cout statement, the output COULD be this?:
No, the order in which output appears on the screen is the same as the order in which std::cout is called. The problem with your original program is that there are two calls to std::cout (one in sd and one in main), who's order is unspecified.
Quote:
Originally Posted by
KingGhidorah
Cout statements in int/float/double functions aren't usual/proper, I guess. Can someone confirm this for me? It was just a result of my tinkering about, no idea if it is ever done for any reason. I am under the impression that cout are usually only included in void functions.
The problem is that you are using std::cout for debugging. That's not the best way, exactly for this reason.
In general it's best to keep I/O separate from actual calculations or program logic. The fact that you output something in your sd function means that this function should now the context in which it is called. That's bad design.
Re: Do functions compute before being called?
In general, my practice is to write "normal" output to cout, and debugging output to cerr.
Re: Do functions compute before being called?
One more question :) So you guys are saying that the order of evaluation in the statements I have written is undefined. E.g. D_Drmmr said,
"No, the order in which output appears on the screen is the same as the order in which std::cout is called. The problem with your original program is that there are two calls to std::cout (one in sd and one in main), who's order is unspecified."
But yet - the output of this program is ALWAYS A:
"Input array element 0: 5
Input array element 1: 7
Input array element 2: 9
7
The standard deviation of these numbers is 1.63299."
And never, for example, B:
"Input array element 0: 5
Input array element 1: 7
Input array element 2: 9
The standard deviation of these numbers is 7
1.63299."
If it were undefined surely the 7 would NOT ALWAYS be before the final sentence? What am I missing here? It seems to me that the order of evaluation is somehow defined.
I am still unsure of when/where exactly my function is executed.
Thanks again
Re: Do functions compute before being called?
Quote:
Originally Posted by
KingGhidorah
One more question :) So you guys are saying that the order of evaluation in the statements I have written is undefined. E.g. D_Drmmr said,
It's not undefined, it's unspecified. That basically means the compiler is free to choose any order. Of course, the compiler won't choose something at random, so it will always produce the same evaluation order (at least, with the same configuration).
Quote:
Originally Posted by
KingGhidorah
If it were undefined surely the 7 would NOT ALWAYS be before the final sentence? What am I missing here? It seems to me that the order of evaluation is somehow defined.
How do you know? Even "undefined" doesn't mean random.
Quote:
Originally Posted by
KingGhidorah
I am still unsure of when/where exactly my function is executed.
Exactly. :thumb:
That's why you should change your code such that you can be sure.
Re: Do functions compute before being called?
Quote:
Originally Posted by
KingGhidorah
If it were undefined surely the 7 would NOT ALWAYS be before the final sentence? What am I missing here? It seems to me that the order of evaluation is somehow defined.
The issue is not what your current compiler will do, the issue is what any compiler may do with your code. If you took your code, and compiled it on a different compiler, you cannot guarantee the order will be the same.
Quote:
I am still unsure of when/where exactly my function is executed.
That's the point -- you are not the only one unsure -- even the creator of the C++ language, Bjarne Stroustrup, is unsure.
The order of processing could be all jumbled up for some reason (the first parameter is processed first, then the fifth parameter is processed second, then the second parameter is processed third, etc.). The only thing guaranteed is at the other end when that function you're calling starts, it will have the correct values.
Regards,
Paul McKenzie
Re: Do functions compute before being called?
A really simple demonstration would be this.
Code:
int x = 0;
F(++x, ++x, ++x);
Parameter parsing is usually either left to right or right to left.
So F is likely to be called with parameters 1, 2, 3 or 3, 2, 1
It's possible it could also be called with any other permutation.
Re: Do functions compute before being called?
Quote:
Originally Posted by
JohnW@Wessex
A really simple demonstration would be this.
Code:
int x = 0;
F(++x, ++x, ++x);
Parameter parsing is
usually either left to right or right to left.
So F is likely to be called with parameters 1, 2, 3 or 3, 2, 1
It's possible it could also be called with any other permutation.
Actually, its even worst than that, because argument evaluation and argument passing do not have to be done at the same time. In this example, the return type of ++x is a reference. So even if the result of the first ++x is 1, the evalutation of the second parameter changes the result of the first argument, after its evaluation, but before its passed, so you could even end up calling f(3, 3, 3);
This, on my system:
Code:
#include <iostream>
void f(int i, int j, int k)
{
std::cout << i << j << k << std::endl;
}
int main()
{
int x1 = 0;
int x2 = 0;
f(++x1, ++x1, ++x1);
f(x2++, x2++, x2++);
}
prints
Re: Do functions compute before being called?
Quote:
Originally Posted by
JohnW@Wessex
It's possible it could also be called with any other permutation.
Quote:
Originally Posted by
monarch_dodra
Actually, its even worst than that, because argument evaluation and argument passing do not have to be done at the same time.
Actually, its even worst than that :), because the evaluation of such a code gives UB ( in that you can rearrange the evaluation sequence in such a way to read and modify the same scalar variable twice between two sequence points )
for example the code
Code:
#include <iostream>
void f(int i, int j, int k)
{
std::cout << i << j << k << std::endl;
}
int main()
{
int x1 = 0;
int x2 = 0;
f(++x1 + x2++, ++x1 + x2++, ++x1 + x2++);
}
outputs "321" on my system; as you can see, there's no rearrangement of the "basic" operations that reproduces the output, therefore UB has been invoked in this case.