I'd make it more general than that: If, in an expression, you use an operation that changes ("writes" to) some resource, then you should not use that same resource anywhere else in that expression (directly or indirectly).
$i++ changes $i so don't use $i anywhere else in an expression that uses $i++ (including either side of the assignment operator). If you need to use $i more than once in an expression, then use $i+1 not $i++ nor ++$i and do the assignment / increment of $i's value outside of the expression.
Another example is that <IN> . <IN> depends on order of evaluation. Each read changes the state of the file handle, impacting what value will be read from it in future.
Then the next concept is what separates expressions in time. In C, they use the term "sequence points" to describe the points in time across which operations will not move. In Perl, ";" and "," are supposed to create sequence points. But Perl also creates aliases so your example using "," runs into problems because the alias is created in a defined order before a change is made and then a value is pulled from the alias after the change.
When you get an alias vs. a copy can be quite subtle in Perl. So you shouldn't rely on "," being a sequence point for things that might get aliased (which includes variables and even ++$i, at least in some implementations of Perl).
Of course, all of this gets rather complicated and isn't obvious so if you'd tried to predefine order of operations you'd probably have been royally screwed when you ran across this wrinkle and then been forced to make Perl make copies in a lot of cases where it doesn't now, making Perl slower.
- tye
In reply to Re^16: Why is the execution order of subexpressions undefined? (1 change => off-limits)
by tye
in thread Why is the execution order of subexpressions undefined?
by BrowserUk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |