1. "Nasty" bug

I came across a couple of posts on the sourceforge mailing list which refers to a bug in 3.1.1 (which was apparently also present in 4.06), but haven't been able to find the code which generated it. Here are the posts :

said...

Wow. You found a really nasty bug in Euphoria 3.1.1. I tried this on 4.0.6 on Linux and it behaves the same way both interpreted and compiled! I tried tracing through this program with trace(1). The global gets updated in the sub routine but then it reverts to its old value when it comes out.

Using gdb on the compiled version is what I would try next.

Shawn Pringle

On 9 June 2016 at 16:55, john Doe <graemeburke@...> wrote:

Hi folks,


I 've been using EU for over 20 years now, it's still my go-to work horse
for just about anything, and to be honest, I usually still use 3.1.1 mainly
cos Rob's stuff is always rock solid. However....


Can anyone tell me how this isn't a serious critter right in the middle of
EU's sequence handling?


Behavior is the same in exe/exw/exwc 311 and eui 405.


Been beating my head against a brick wall for 2 days and was stunned at
what I found... more amazed that I've never noticed it before in 10 jillion
hours of using eu.


comments?

Graeme Burke

Anyone remember this? it was posted in 2016. It would be nice to know how to avoid this bug...

new topic     » topic index » view message » categorize

2. Re: "Nasty" bug

Perhaps:

https://sourceforge.net/p/rapideuphoria/mailman/rapideuphoria-develop/?viewmonth=201606

It's called lost_ball.ex, and is an attachment on the second message on that page.

Too big to post here.

Good luck cleaning it up so as to prove or disprove the error.

new topic     » goto parent     » topic index » view message » categorize

3. Re: "Nasty" bug

By removing the extraneous stuff, this shows the bug:

with trace 
trace(1) 
 
sequence our_place = {{0}, {{0,0,0,0,0}} } 
 
constant ball = 88 
 
function you(integer thing) 
  integer score = rand(5) 
 
   our_place[2][1][score] = thing 
   puts(1,"You ") ? our_place     
 
return score 
end function 
 
    puts(1,"Me 1 ") 
    ? our_place[2] 
     
    our_place[1][1]  +=  you( ball ) -- here is problem. 
     
    --integer x = you(ball) -- separating the steps works 
    --our_place[1][1] += x 
     
    puts(1,"Me 2 ") 
    ? our_place[2] 
     
    puts(1,"Done") 
                                   
new topic     » goto parent     » topic index » view message » categorize

4. Re: "Nasty" bug

Hi Irv,

I had a look at this and discovered 2 things...

1. Phix gets it right.
2. There's a note in the 3.1.1 documentation about exactly this case. It reads..

The expressions are evaluated, and any subscripting is performed, from left to right. It is possible to have function calls in the right-hand-side expression, or in any of the left-hand-side expressions. If a function call has the side-effect of modifying the lhs_var, it is not defined whether those changes will appear in the final value of the lhs_var, once the assignment has been completed. To be sure about what is going to happen, perform the function call in a separate statement, i.e. do not try to modify the lhs_var in two different ways in the same statement. Where there are no left-hand-side subscripts, you can always assume that the final value of the lhs_var will be the value of rhs_expr, regardless of any side-effects that may have changed lhs_var.

Les

new topic     » goto parent     » topic index » view message » categorize

5. Re: "Nasty" bug

Thanks. It is still there in 4.1b2

I'm not sure whether this is a bug or a "feature". Most programming languages have lots of "features" like this:)

Anyway, for some reason, in all the coding I have done, the problem has never presented itself before.

new topic     » goto parent     » topic index » view message » categorize

6. Re: "Nasty" bug

How about "a documented shortcoming". smile

new topic     » goto parent     » topic index » view message » categorize

7. Re: "Nasty" bug

Thanks a lot for the feedback guys, interesting. I've never come across this scenario myself, but good to be reminded that it exists.

new topic     » goto parent     » topic index » view message » categorize

8. Re: "Nasty" bug

irv said...

Anyway, for some reason, in all the coding I have done, the problem has never presented itself before.

Same here. I'm not sure if this counts as a bug, or simply a side-effect of the logic of the code parser. There's a logic error in the code parser because there's a logic error in the code that was written. Euphoria doesn't, for better or worse, tell the user what "good" code should be. This is one of the rare examples where writing bad code leads to weird side-effects and undefined behavior.

If you're looking for a solution to avoiding this problem, I have but one word: abstraction. If you need to store data in memory and manipulate it elsewhere, do yourself a favor and write a library with all of the functions required to manage the data without having to touch the variable(s) that holds the data directly.

This problem would have continued unnoticed had the original author of the code written it in such a way as to conceptualize the actions in code first. I have to imagine that the code posted was merely an example to demonstrate the problem, but that worries me even more as to what the author's original code looks like!

Overall, I don't if this something that should be fixed or not. On one hand, yes it's a weird logic error. But on the other, the expected behavior is undefined. If we can detect the problem in the parser, then maybe we should just issue a warning, like Warning { side_effect }: lhs_var will not be updated due to side-effect in function func_name.

-Greg

new topic     » goto parent     » topic index » view message » categorize

9. Re: "Nasty" bug

ghaberek said...

This problem would have continued unnoticed had the original author of the code written it in such a way as to conceptualize the actions in code first. I have to imagine that the code posted was merely an example to demonstrate the problem, but that worries me even more as to what the author's original code looks like!

The original code was lost_ball.ex, linked above. It appears to be a Eu translation from some other language, perhaps basic, which of course makes it messy. Probably just an accident that the one line happened to uncover a problem. The code I show was the original pared down to the minimum to show the error.

There's an additional "gotcha" involved. Some experimenting I did:

sequence our_place = {{0}, {{0,0,0,0,0}} } -- fails 
sequence our_place = {0,{{0,0,0,0,0}} -- make first an atom, 
    our_place[1]  +=  you( ball ) -- and it works 

If the first element of the sequence is an atom, the problem doesn't occur.

new topic     » goto parent     » topic index » view message » categorize

10. Re: "Nasty" bug

Another variation on "dropping the ball."

oE works "as expected"; Phix gives a different result when index is one (1).

constant ball = 88 
sequence blank = { 0,0,0,0,0 } 
sequence lst  
 
 
for index = 1 to 5 do 
 
puts(1, "\n----------------------------------------- no assignment \n" ) 
 
    lst = blank 
    printf(1,"Outside lst value    %g %g %g %g %g \n\n", lst ) 
    ? set(ball, index) 
    printf(1,"Outside lst value    %g %g %g %g %g \n", lst ) 
 
puts(1, "\n----------------------------------------- with += assignment\n" ) 
 
    lst = blank 
    printf(1,"Outside lst value    %g %g %g %g %g \n\n", lst ) 
    lst[1] += set( ball, index) 
 
    printf(1,"Outside lst value    %g %g %g %g %g \n\n", lst ) 
 
 
puts(1, "\n----------------------------------------- with staged assignment\n" ) 
 
    lst = blank 
    printf(1,"Outside lst value    %g %g %g %g %g \n\n", lst ) 
 
    integer NDX = set(ball, index) 
    lst[1] += NDX 
    printf(1,"Outside lst value    %g %g %g %g %g \n\n", lst ) 
 
puts(1, "\n-----------------------------------------\n" ) 
 
    ? gets(0) -- pause to review results 
    clear_screen() 
 
end for 
 
 
function set(integer thing, integer index)  
  lst[index] = thing 
          printf(1,"           Inside set argument %g\n", thing ) 
          printf(1,"           Inside set index    %d\n", index ) 
          printf(1,"           Inside set value    %g %g %g %g %g \n", lst ) 
  return index 
end function  
 
      
puts(1,"\n\n                              Done")  

_tom

new topic     » goto parent     » topic index » view message » categorize

11. Re: "Nasty" bug

_tom said...

oE works "as expected"; Phix gives a different result when index is one (1).

    lst[1] += set( ball, index) 

If you replace that with

    lst[1] = lst[1] + set( ball, index) 

Then eui and phix behave the same.

I think I have a slight preference for "lst[1] +=" always behaving exactly the same as "lst[1] = lst[1] +", and hence have no plans to change anything.

Pete

new topic     » goto parent     » topic index » view message » categorize

12. Re: "Nasty" bug

I do not have a simple way to document the failure of oE for this "Nasty" bug.

This works. So the trap is set.

-- Version 1 
 
constant ball = 88 
sequence our_place = { 0, {0,0,0,0,0} }  
  
function you(integer thing)  
  integer score = rand(5) 
  our_place[2][score] = thing 
  printf(1, "__________________________ score %d \n", score ) 
    puts(1, "Inside  " ) ? our_place  
  return score  
end function  
 
for i=1 to 5 do 
    our_place[1] += you( ball )        -- OK 
    puts(1, "Outside ") ? our_place 
end for 
      
puts(1,"Done")  

Increasing the nesting of the sequence results in failure.

-- Version 2 
 
constant ball = 88 
  
sequence our_place = { {0}, {{0,0,0,0,0}} }   -- increased nesting  
  
function you(integer thing)  
  integer score = rand(5) 
  our_place[2][1][score] = thing 
      printf(1, "__________________________ score %d \n", score ) 
      puts(1, "Inside  " ) ? our_place  
  return score  
end function  
 
for i=1 to 5 do 
    our_place[1][1] += you( ball )        -- eui euc FAILING 
       puts(1, "Outside ") ? our_place 
end for 
      
puts(1,"Done")  

There is a fix

-- Version 3 
 
constant ball = 88 
  
sequence our_place = { {0}, {{0,0,0,0,0}} }   -- increased nesting  
  
function you(integer thing)  
  integer score = rand(5) 
  our_place[2][1][score] = thing 
      printf(1, "__________________________ score %d \n", score ) 
      puts(1, "Inside  " ) ? our_place  
  return score  
end function  
 
for i=1 to 5 do 
    atom tmp = you(ball)                --eui euc requires this fix 
    our_place[1][1] += tmp 
       puts(1, "Outside ") ? our_place 
end for 
      
puts(1,"Done")  
  • Phix works all of the time
  • oE does not work uniformly
    avoid functions that have side-effects!

_tom

new topic     » goto parent     » topic index » view message » categorize

13. Re: "Nasty" bug

_tom said...

I do not have a simple way to document the failure of oE for this "Nasty" bug.

See the italic quote in #4, and the technicalia drop-down on http://phix.x10.mx/docs/html/seqformation.htm
It is also mentioned on http://phix.x10.mx/docs/html/multiassign.htm in the "Update" of "How NOT to use multiple assignment".

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu