Argument evaluation order and byref (from: What is randomize / rnd ?)
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
by the fact that gcc outputs Pi/4 means that both parameters to atan2 have the same value, apparently the num function is called only once
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
It is as if 'a' and 'b' were passed by reference (or by pointer) to myfunction (and not by value).dodicat wrote: ↑Aug 14, 2024 15:41Hi srvaldez.
No options bar -gen gcc when testing 32 bits.
tested fbide and command line
I have simplified this, no static variable and no byref function, just straight pointer.fb 1.10.1 winlibs -gcc-9.3 (the present standalone distro)Code: Select all
Dim Shared As Integer u Function num() As Integer Ptr u+=50 Print u Return @u End Function Function myfunction(a As Integer,b As Integer) As Double Print "return value = ";a;"/";b Return a/b End Function Print Atan2(*num,*num) 'a freebasic built in Print Atan2(50,100) Print Print myfunction(*num,*num) ' a made procedure Print myfunction(150,200) Sleep
Maybe a quick optimization of the generated code (the argument being available by reference (or by pointer))!
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
fxm
You can put in a bug report if you like, thank you.
You can put in a bug report if you like, thank you.
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
FYI
First issue in gas64 fixed (an optimization in generated asm code prevented a correct converting ulong to integer).
Currently working on a second bug (byref function).
First issue in gas64 fixed (an optimization in generated asm code prevented a correct converting ulong to integer).
Currently working on a second bug (byref function).
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
I tried gcc proper
code:
Results both 32 bit and 64 bit gcc compiler
code:
Code: Select all
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int * num()
{
static int u=0;
u+=50;
printf("%d\n",u);
return &u;
}
double myfunction(int a,int b)
{
printf("%s %d %s %d \n" ,"return value = ",a,"/",b);
return (double)(a)/(double)(b);
}
int main()
{
printf("%f\n",atan2(*num(),*num()));
printf("%f\n",atan2(50,100));
printf("\n");
printf("%.5f\n", myfunction(*num(),*num()) ); // a made procedure
printf("%.5f\n", myfunction(150,200));
system("pause");
}
Code: Select all
50
100
1.107149
0.463648
150
200
return value = 200 / 150
1.33333
return value = 150 / 200
0.75000
Press any key to continue . . .
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
What bothers me a little to fill out a bug report is that the code used is not safe, even when the function returns by value.
Indeed, there is no constraint on the order of evaluation of the arguments passed to a procedure compared to its declaration (from the last parameter to the first or vice versa?);
Which means that when the value returned by the function varies with each call, a precise behavior is not ensured seen from the procedure body.
gas and gcc/gas64 have a different behavior on unsafe code. Is this a bug?
Test program:
Output with gas(32):
Output with gcc(32/64) or gas64:
Indeed, there is no constraint on the order of evaluation of the arguments passed to a procedure compared to its declaration (from the last parameter to the first or vice versa?);
Which means that when the value returned by the function varies with each call, a precise behavior is not ensured seen from the procedure body.
gas and gcc/gas64 have a different behavior on unsafe code. Is this a bug?
Test program:
Code: Select all
Function ReturnByVal() As Integer
Static As Integer I
I+= 1
Return I
End Function
Function ReturnByRef() Byref As Integer
Static As Integer I
I+= 1
Return I
End Function
Function ReturnByPtr() As Integer Ptr
Static As Integer I
I+= 1
Return @I
End Function
Sub Test(Byval I1 As Integer, Byval I2 As Integer, Byval I3 As Integer)
Print " First received parameter : " & I1
Print " Second received parameter : " & I2
Print " Third received parameter : " & I3
End Sub
Print "Arguments are function returns by value)
Test(ReturnByVal(), ReturnByVal(), ReturnByVal())
Print
Print "Arguments are function returns by reference)
Test(ReturnByRef(), ReturnByRef(), ReturnByRef())
Print
Print "Arguments are function returns by pointer)
Test(*ReturnByPtr(), *ReturnByPtr(), *ReturnByPtr())
Sleep
Code: Select all
Arguments are function returns by value)
First received parameter : 3
Second received parameter : 2
Third received parameter : 1
Arguments are function returns by reference)
First received parameter : 3
Second received parameter : 2
Third received parameter : 1
Arguments are function returns by pointer)
First received parameter : 3
Second received parameter : 2
Third received parameter : 1
Code: Select all
Arguments are function returns by value)
First received parameter : 3
Second received parameter : 2
Third received parameter : 1
Arguments are function returns by reference)
First received parameter : 3
Second received parameter : 3
Third received parameter : 3
Arguments are function returns by pointer)
First received parameter : 3
Second received parameter : 3
Third received parameter : 3
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
looks like the gcc C compiler is loading the parameters in reverse order both with the math.h atan2 and myfunction.
Whereas fb is loading correctly (this simple function) with gcc and giving same result as the c compiler.
Whereas the gas fb is loading atan2 in order and myfunction in reverse order.
this simple code is surely safe.
Whereas fb is loading correctly (this simple function) with gcc and giving same result as the c compiler.
Whereas the gas fb is loading atan2 in order and myfunction in reverse order.
this simple code is surely safe.
Code: Select all
Function num() As Integer
static as integer u
u+=50
Print u
Return u
End Function
Function myfunction(a As Integer,b As Integer) As Double
Print "return value = ";a;"/";b
Return a/b
End Function
Print Atan2(num,num) 'a freebasic built in
Print Atan2(50,100)
Print
Print myfunction(num,num) ' a made procedure
Print myfunction(150,200)
Sleep
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
Bug explained with this code.
Snippet of C code :
The C version stores the addresses for returned values not the values.
The problem is that they are the same and after the second call the first return value is replaced by the new one.....
Code: Select all
Function Rnd2() byref As integer
Static As Ulong seed_value
Static As integer d
seed_value = (seed_value * 2 + 10 )
d=seed_value
Return d
End Function
screen 20,32
rnd2()=200
circle(rnd2*5,rnd2*4),30,rgb(255,120,40),,,,f
Code: Select all
int64* vr$2 = RND2( );
int64* vr$5 = RND2( );
fb_GfxEllipse( (void*)0ull, (float)(*vr$5 * 5ll), (float)(*vr$2 << (2ll & 63ll))
The problem is that they are the same and after the second call the first return value is replaced by the new one.....
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
Based on your example.
With test(byval....) gas32 pushes immediately the values on stack after each call.
Instead gcc/gas64 store the addresses then use them after all the calls. Obviously the last and same value is used for the 3 parameters.
With test(byref...) we get the same result for all the versions.
With test(byval....) gas32 pushes immediately the values on stack after each call.
Instead gcc/gas64 store the addresses then use them after all the calls. Obviously the last and same value is used for the 3 parameters.
With test(byref...) we get the same result for all the versions.
As different behaviours between the versions it's a bug, however which one is the right oneIs it a bug ?
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
Yes, but my philosophical question is:
Is the different behavior of gas and gcc/gas64 on the same code a bug when the code is not safe ?
Indeed, there is no constraint (in my opinion) on the order of evaluation of the arguments passed to a procedure compared to its declaration (from the last parameter to the first, or vice versa ?).
Which means that when the value returned by the function varies with each call, a precise behavior is already not ensured seen from the procedure body on its received parameters.
Is the different behavior of gas and gcc/gas64 on the same code a bug when the code is not safe ?
Indeed, there is no constraint (in my opinion) on the order of evaluation of the arguments passed to a procedure compared to its declaration (from the last parameter to the first, or vice versa ?).
Which means that when the value returned by the function varies with each call, a precise behavior is already not ensured seen from the procedure body on its received parameters.
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
The order of evaluation is correct, not a problem of first/last.
The difference is that the source (value) is changed when retrieved before the call for the 2 first parameters.
3 solutions:
- gas32 behaves like the other versions
- gcc/gas64 behave like gas32
- forbid a such code : multiple calls to a byref function used as parameter. Force to use temporary variables.
The difference is that the source (value) is changed when retrieved before the call for the 2 first parameters.
3 solutions:
- gas32 behaves like the other versions
- gcc/gas64 behave like gas32
- forbid a such code : multiple calls to a byref function used as parameter. Force to use temporary variables.
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
The function does not need to be byref, the variable incrementing can be shared as I posted previously.SARG wrote: ↑Aug 15, 2024 10:41 The order of evaluation is correct, not a problem of first/last.
The difference is that the source (value) is changed when retrieved before the call for the 2 first parameters.
3 solutions:
- gas32 behaves like the other versions
- gcc/gas64 behave like gas32
- forbid a such code : multiple calls to a byref function used as parameter. Force to use temporary variables.
Here is an update with my own atan2, to see the input values, and resetting the shared variable each time.
(fxm what do you mean by unsafe code?)
Code: Select all
Dim Shared As Integer u
Function num() As Integer Ptr
u+=50
Print u
Return @u
End Function
Function MyATN(Byval x As Double) As Double
Dim As Double y,temp=x
Dim As Uinteger limit=16, f=2^limit
For n As Integer =1 To limit
y=temp/(1+Sqr(1+temp*temp))
temp=y
Next n
Dim As Double accum
Dim As Integer c=1,counter,sign
Dim As Double xx=y*y,term,p=y,temp1=y,temp2
Do
c+=2
temp2=temp1
counter+=1
p=p*XX
term=p/c
If (counter And 1) Then sign=-1 Else sign=1
accum=temp1+sign*term
temp1=accum
Loop Until temp1=temp2
Return f*accum
End Function
Function MyAtan2(Byval x As Double,Byval y As Double) As Double
Print "input value = ";x;",";y
Dim k As Integer
Dim As Double pi=4*MyATN(1),temp
If y=0 Then Return Sgn(x)*pi/2
If Sgn(y)=1 Or Sgn(y)=0 Then k=0 Else k=1
k=k*Sgn(x)
If x=0 And y=0 Then Return 0
If Sgn(x)=0 And Sgn(y)=-1 Then Return Pi
temp=MyATN(x/y)
Return (temp)+k*Pi
End Function
Function myfunction(a As Integer,b As Integer) As Double
Print "return value = ";a;"/";b
Return a/b
End Function
Print Atan2(*num,*num),"fb atan2 using the function num()" 'a freebasic built in
Print Atan2(50,100),"fb atan2 using the numbers above from function num()"
u=0
Print
Print myfunction(*num,*num) ' a made procedure
Print myfunction(50,100)
print
u=0
print myatan2(*num,*num),"My atan2 using the function num()"
print myatan2(50,100),"My atan2 using the numbers above from function num()"
Sleep
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
I apologize, but I repeat the same question again:
Is there a specification that imposes the order of evaluation of the parameters passed to a procedure (case of parameters passed by value)?
gcc(32/64) and gas(32/64) evaluate them from the last to the first (compared to the procedure declaration), but is this order specified anywhere?
If there is no evaluation order specified, using it like this in his code corresponds to unsafe (unsecure / dangerous) code.
Is there a specification that imposes the order of evaluation of the parameters passed to a procedure (case of parameters passed by value)?
gcc(32/64) and gas(32/64) evaluate them from the last to the first (compared to the procedure declaration), but is this order specified anywhere?
If there is no evaluation order specified, using it like this in his code corresponds to unsafe (unsecure / dangerous) code.
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
If you do pascal
viz
Function MyAtan2 pascal(Byval x As Double,Byval y As Double) As Double
...
and
Function myfunction pascal(a As Integer,b As Integer) As Double
...
gas loads in the correct order.
(but should you really have to gp pascal)
but gcc still errors.
viz
Function MyAtan2 pascal(Byval x As Double,Byval y As Double) As Double
...
and
Function myfunction pascal(a As Integer,b As Integer) As Double
...
gas loads in the correct order.
(but should you really have to gp pascal)
but gcc still errors.