Re: Function call evaluation order
- From: "Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@xxxxxxxxxxxxxxx>
- Date: Sat, 25 Mar 2006 14:50:21 -0800
"Frederico Pissarra" <fredericopissarra@xxxxxxxxx> wrote in message
news:OFqau3EUGHA.2156@xxxxxxxxxxxxxxxxxxxxxxx
My intent isn't to make anyone angry at me here... hehe...
I'm testing every scenario you guys are posting here and trying to
understand why you consider those codes having "undefined" behaviour...
What I am seeing, as an experienced C/C++ developer, is that precedence
and associativity can explain everything here...
Pardon me, but rubbish! Go back and look at my example with f1(), f2() and
f3(), but rewrite it to have all three "functions" inline in main():
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
template <class T>
T inc(T& i)
{
T t = i;
++i;
return t;
}
int main()
{
char* data[] = { "one ", "two ", "three " };
int i = 0;
string s;
// f1
s.assign(data[i++]).append(data[i++]).append(data[i++]);
cout << s << endl;
i = 0;
// f2 - comment the next two lines out and see the result of f1 change!
s.assign(data[inc(i)]).append(data[inc(i)]).append(data[inc(i)]);
cout << s << endl;
i = 0;
// f3
s.assign(data[i++]);
s.append(data[i++]);
s.append(data[i++]);
cout << s << endl;
}
How do you propose to explain in terms of precedence and associativity the
fact that commenting out "f2" in this program changes the output of f1? It
simply can't be done. Try it! Compile and it with VC7.1 or VC8 with or
without optimization, then comment out (or delete) "f2" and try it again.
I'm sorry, but precedence and associativity simply don't fully define the
order of evaluation for expressions like f1 or f2.
In the last piece of code I expected to see 0 0 0 and 3 3 3... and it is
what happen!
Your expectations have been tuned to match what your compiler does!
According to the C++ standard, the results of both are undefined.
I can't see what is "undefined" here...
expressions using ++ or -- can be very confusing sometimes, but to me they
aren't "undefined"...
Again, you're missing the point. No single increment is undefined. What's
undefined is the relative order in which they execute in a single expression
that modifies the same variable more than once.
Until now all of you failed to define what "undefined" is... Igor
Tandetnik gave a nice view of "undefined" calling sequence (and that
explanation I can understand and accept)...
Undefined behavior is behavior that is not defined by the C++ standard. The
behavior of any particular compiler has absolutely nothing to do with what
is or is not undefined behavior.
Relevant to this discussion, undefined behavior occurs when a single object
is modified twice between sequence points. In the original expression
s.assign(data[i++]).append(data[i++]).append(data[i++])
the variable i is modified three times and there ARE NO SEQUENCE POINTS
between those increments. That fact that you can make an argument why the
compiler generated code a certain way based on precedence and associativity
doesn't make the behavior well-defined according to the C++ standard.
Get the C++ standard and understand what we're talking about! As an
experienced developer, you should know what is and is not defined according
to the standard, and the values of expressions like int j = i++ + i++; are
simply not defined. Dressing it up with function calls and object
references may convince you that the result of
s.assign(data[i++]).append(data[i++]).append(data[i++]) is well defined, but
at its core it's no different than i++ + i++. Relying on the observable
behavior of the compiler to define your concept of "defined behavior" is
risky because a future version of the compiler, or another company's
compiler might produce a different result if you've relied on behavior
that's not defined by the standard.
Please, don't be angry! :)
No worries!
-cd
.
- Follow-Ups:
- Re: Function call evaluation order
- From: Abdo Haji-Ali
- Re: Function call evaluation order
- From: Frederico Pissarra
- Re: Function call evaluation order
- References:
- Function call evaluation order
- From: Cheng
- Re: Function call evaluation order
- From: Frederico Pissarra
- Re: Function call evaluation order
- From: Carl Daniel [VC++ MVP]
- Re: Function call evaluation order
- From: Frederico Pissarra
- Re: Function call evaluation order
- From: Carl Daniel [VC++ MVP]
- Re: Function call evaluation order
- From: Frederico Pissarra
- Re: Function call evaluation order
- From: Carl Daniel [VC++ MVP]
- Re: Function call evaluation order
- From: Carl Daniel [VC++ MVP]
- Re: Function call evaluation order
- From: Frederico Pissarra
- Re: Function call evaluation order
- From: Tom Widmer [VC++ MVP]
- Re: Function call evaluation order
- From: Frederico Pissarra
- Function call evaluation order
- Prev by Date: Re: BSTR, _bstr_t issues occuring on our Windows 2003 Server
- Next by Date: Re: ERROR_DLL_INIT_FAILED - HELP please
- Previous by thread: Re: Function call evaluation order
- Next by thread: Re: Function call evaluation order
- Index(es):
Relevant Pages
|