It is currently Mon Dec 11, 2017 6:38 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Bug when appending return value of procedure to a string
PostPosted: Sun Apr 16, 2017 9:00 pm 
Offline
New User
New User

Joined: Sun Apr 16, 2017 8:46 pm
Posts: 6
Location: Germany
Hi!

I think I found a bug in the PureBasic compiler.
When modifying a string variable from within a procedure that returns a string
and then appending the returned string to the same variable,
the modifications done by the procedure are lost.
I'm using PureBsic 5.60 64 bit on Windows 7 SP1 64 bit.
The following code will demonstrate this problem:
Code:
Procedure.s returnstring(*s.String)
  *s\s + "abc"
  ProcedureReturn "xyz"
EndProcedure

*mystr.String = AllocateStructure(String)

; This is line optional.
; The bug is independent of whether a value has been assigned to the string or not.
*mystr\s = "123"

; This is where the bug occurs.
; This line calls the function returnstring() which first appends "abc" and then returns "xyz".
; When the returned string is appended, the "abc" is lost.
*mystr\s + returnstring(*mystr)

; This is a workaround using a temporary string.
; temp$ = returnstring(*mystr)
; *mystr\s + temp$

; Should be "123abcxyz", but is actually "123xyz".
Debug *mystr\s

The above example uses a string member of a dynamically allocated structure, because this is what my actual program does as well.
However, the bug also occurs when using a simple global variable, like in the follwing example:
Code:
Global string$

Procedure.s returnstring()
  string$ + "abc"
  ProcedureReturn "xyz"
EndProcedure

string$ = "123"

string$ + returnstring()

; Should be "123abcxyz"
Debug string$

I hope this is a bug (and not a feature :)) and that it will get fixed soon, but there's no hurry.

Cheers
Nils


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Sun Apr 16, 2017 9:17 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5747
Location: Germany
Its not a bug, it is the expected behavior.

Code:
*mystr\s + returnstring(*mystr)


This is just a short form for:

Code:
*mystr\s = *mystr\s + returnstring(*mystr)


Expressions are evaluated left to right, so to compute the value that is placed inside the final result, the first thing that is evaluated is *mystr\s which at this point only holds the value "123". The procedure is called after this part has been evaluated. This means no matter what you do inside the procedure to *mystr\s, it cannot have an effect on the result since this part has already been evaluated by the time the procedure is called.

It is a simple result of the evaluation rules and no bug.

_________________
quidquid Latine dictum sit altum videtur


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Sun Apr 16, 2017 9:57 pm 
Offline
New User
New User

Joined: Sun Apr 16, 2017 8:46 pm
Posts: 6
Location: Germany
freak wrote:
Its not a bug, it is the expected behavior.

Okay, now I understand the reason for this behavior, but I still think it's confusing,
because when I see something like "a + b()" I wouldn't expect that the compiler understands it as "a = a + b()".
The documentation unfortunately is not very clear about this topic. Only this example
Code:
  Dim MyArray(10)
  MyArray(Random(10)) + 1 ; The same as: MyArray(Random(10)) = MyArray(Random(10)) + 1, but here Random() won't return the same value for each call.

might give a hint about the problem.

Nils


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Sun Apr 16, 2017 10:21 pm 
Offline
Enthusiast
Enthusiast

Joined: Mon Feb 04, 2013 5:28 pm
Posts: 309
You are not alone :lol:

viewtopic.php?f=12&t=51251

I think the example you mentioned was written in reply to the thread above


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Sun Apr 16, 2017 11:59 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5747
Location: Germany
I just used the long form for explanation. The behavior is a result of the expression evaluation order and has actually nothing to do with how the short form is treated. Since the procedure is the second thing in the expression, it cannot affect the parts of the expression that were already evaluated. It works like that in pretty much any language.

Don't believe me? Try the same in C or Java and tell me the result ;)

_________________
quidquid Latine dictum sit altum videtur


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Mon Apr 17, 2017 2:45 am 
Offline
New User
New User

Joined: Sun Apr 16, 2017 8:46 pm
Posts: 6
Location: Germany
Just tried it.
Code:
#include <stdio.h>

int myfunc(int *intptr) {
   *intptr += 200;
   return 10;
}

int main(int argc, char *argv[]) {

   int myint = 3000;
   myint = myint + myfunc(&myint);
   printf("myint = %i\n", myint);

   return 0;

}

C code compiled with Pelles C wrote:
myint = 3210

Probably it's a just very bad idea to modify a variable within a function that is called in an expression that uses the same variable.
I guess the result of this is simply undefined because of unpredictable optimizations done by the C compiler.

Nils


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Mon Apr 17, 2017 10:52 am 
Offline
Enthusiast
Enthusiast

Joined: Mon Feb 04, 2013 5:28 pm
Posts: 309
freak wrote:
Don't believe me? Try the same in C or Java and tell me the result


... wait for it ....

NilsH wrote:
Just tried it.


Ach, you beat me to it !

NilsH wrote:
Probably it's a just very bad idea to modify a variable within a function that is called in an expression that uses the same variable.


Maybe it's not a great idea, but the result with the C compiler (C++ also gives the same result, with optimizations on or off) is what you expected and it's different from what pb does.


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Mon Apr 17, 2017 12:42 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5747
Location: Germany
Guess I have been working on the Java side of things for too long...

Code:
public class Test {
   
   static int a = 1;
   
   public static int b() {
      
      a = 999;
      return 1;
   }

   public static void main(String[] args) {

      a += b();
      System.out.println(a);
   }
}


Result is 2. Now what? :)

Anyway, the expression evaluation order is something that every language has to define for itself and it affects how such code behaves. Some languages explicitly define this one way or the other, others leave it undefined for optimization reasons. Still, it is a design decision and not a bug.

Imagine if it worked the other way around. Somebody could just as easily write a bug report because he expected the current behavior. There is no "right" way to do this.

You already found the only sane way to deal with this:

NilsH wrote:
Probably it's a just very bad idea to modify a variable within a function that is called in an expression that uses the same variable.

_________________
quidquid Latine dictum sit altum videtur


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Mon Apr 17, 2017 10:25 pm 
Offline
Enthusiast
Enthusiast

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 653
Location: right here
just because the c code does something in some way with some compiler, that doesn't say anything.

Quote:
http://en.cppreference.com/w/cpp/language/eval_order

Undefined behavior

Code:
i = ++i + i++; // undefined behavior
i = i++ + 1; // undefined behavior
i = ++i + 1; // undefined behavior (well-defined in C++11)
++ ++i; // undefined behavior (well-defined in C++11)
f(++i, ++i); // undefined behavior
f(i = -1, i = -1); // undefined behavior


Code:
cout << i << i++; // undefined behavior
a[i] = i++; // undefined behavior


you should just avoid so called 'side effects'. it's just not immediately obvious that this pb shortcut statement has side effects. but now you know it :P


Top
 Profile  
Reply with quote  
 Post subject: Re: Bug when appending return value of procedure to a string
PostPosted: Mon Apr 17, 2017 10:52 pm 
Offline
Enthusiast
Enthusiast

Joined: Mon Feb 04, 2013 5:28 pm
Posts: 309
I agree, let's drop this and concentrate on the other compiler's and ide's bugs.

Let's forget this, it's fine.

Deal ? :wink:


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye