Jump to content

Recommended Posts

Hello,

 

This might seem silly. Used a few programming languages over the years. Would you expect the code below to produce the same result? 7

Did not find a reference in the help system.

procedure TestOrder;
var
 index,finalValue:integer;

 function ResultIsFive(var i:integer):integer;
 begin
  result:= 3 + 2;
  Inc(i);
 end;

begin
  index:=1;
  finalValue:=index + ResultIsFive(index);
  ShowMessage(IntToStr(finalValue));

  index:=1;
  finalValue:=ResultIsFive(index) + index;
  ShowMessage(IntToStr(finalValue));
end;

Thanks,

 

Mark

Share this post


Link to post
9 minutes ago, Mark- said:

Would you expect the code below to produce the same result? 7

Yes. Order is not important here because the function must be run before the expression can be evaluated.

Share this post


Link to post

Hi Mark,

 

no, compiler in my head says, 6 and 7. index passed as var, i is index, index is i and you inc it, change the order of your addition.

 

dave

  • Like 1

Share this post


Link to post
1 hour ago, corneliusdavid said:

Yes. Order is not important here because the function must be run before the expression can be evaluated.

No I don't think that is true. 

Share this post


Link to post

This code exhibits undefined behaviour. In an expression like a + b, a and b can be evaluated in either order. The language does not mandate that order. 

 

If you want to make your code well defined the. You need to evaluate the function on one statement, and then perform the addition in another. 

 

finalValue := ResultIsFive(index);

Inc(finalValue, index);

 

Edited by David Heffernan
  • Like 1

Share this post


Link to post
25 minutes ago, David Heffernan said:

In an expression like a + b, a and b can be evaluated in either order.

Yes, for simple variables but I'm pretty sure that functions have to be evaluated first. I ran a simple test of OP's code and verified before I answered. I ran it in Delphi 10.4; perhaps an earlier version of Delphi (or a compiler directive?) would change that.

 

29 minutes ago, David Heffernan said:

If you want to make your code well defined then you need to evaluate the function on one statement, and then perform the addition in another.

I totally agree with this. 

Share this post


Link to post

I've also tested:

 

finalValue:=2*index + ResultIsFive(index);

 

the result 9. I guess this is one of the reasons why you should not write procedures with side effects. It can make a mission impossible to find the them.

Share this post


Link to post
8 hours ago, corneliusdavid said:

I'm pretty sure that functions have to be evaluated first. I ran a simple test of OP's code and verified before I answered.

That just tells you about this one piece of code and whichever compilers you happened to use. It doesn't prove a rule. 

 

If you look in a field and see that all the cows in that field are back and white, does that prove that all cows are black and white? 

Share this post


Link to post
9 hours ago, corneliusdavid said:

I'm pretty sure that functions have to be evaluated first.

I'm pretty sure you are wrong and that it is not specified in languages.

 

Share this post


Link to post
2 hours ago, FPiette said:

I'm pretty sure you are wrong and that it is not specified in languages.

Usually it is left to right like in C# which is one of the few languages that has very little UB - https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#12623-run-time-evaluation-of-argument-lists

Edited by Stefan Glienke

Share this post


Link to post
13 hours ago, David Heffernan said:

No I don't think that is true. 

In this case it is, but one should never make assumptions about in which order the parts of a complex expressions are evaluated. It may even change depending on compiler flags, e.g. optimization on or off, stack frames on or of, range and overflow checks.

Share this post


Link to post
1 hour ago, PeterBelow said:

In this case it is

I never said anything about this specific case. I am referring to universal rules that can be applied, or in this case not because they don't exist. See the black and white cow argument. 

Share this post


Link to post
9 hours ago, Lajos Juhász said:

finalValue:=2*index + ResultIsFive(index);

 

the result 9

My test in FPC, the result is 7,  so don't rely on the order.

Share this post


Link to post
1 hour ago, flcop said:

My test in FPC, the result is 7,  so don't rely on the order.

If FPC had given 9 that wouldn't have changed the conclusion 

  • Haha 1

Share this post


Link to post

I found this in my usenet archives about the evaluation order:

Quote

The order of side effects in sub-expressions is not consistent.
It may be changed in future. You should not write a code depending on it.

Yooichi Tagawa (Delphi Compiler R&D, Embarcadero)

Quote

Additionally, as the optimizer gets more sophisticated, the ordering
could further change depending on whether optimizations are on or off.

Allen Bauer
Embarcadero Chief Scientist

 

  • Like 3
  • Thanks 3

Share this post


Link to post
4 hours ago, Anders Melander said:

I found this in my usenet archives about the evaluation order:

 

Thank you.

Share this post


Link to post
17 hours ago, David Heffernan said:

That just tells you about this one piece of code and whichever compilers you happened to use. It doesn't prove a rule. 

True. Somewhere back in time, I thought I had heard or read this and well, it made sense (to me) and a quick test of this one particular case in one particular version of Delphi confirmed my thinking but you're right, it certainly does not prove a rule. The much, MUCH better way is to just avoid writing obscure code in the first place. :classic_cool:

  • Like 1

Share this post


Link to post
16 hours ago, Anders Melander said:

as the optimizer gets more sophisticated

And there I am, still hoping for that day to come

  • Haha 3

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×