Ideally you should have started a new thread.dodicat wrote:Sorry for going severely off the thread topic Löwenherz.
Argument evaluation order and byref (from: What is randomize / rnd ?)
-
- Posts: 4705
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
deltarho[]
A lot of my recent generators are byref, so you can easily seed them , i.e. change a value inside the generator from outside.
But it looks like they have all gone to the wall now in -gen gcc.
Maybe our developers will repair things.
A lot of my recent generators are byref, so you can easily seed them , i.e. change a value inside the generator from outside.
But it looks like they have all gone to the wall now in -gen gcc.
Maybe our developers will repair things.
-
- Posts: 4705
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
Why?dodicat wrote:But it looks like they have all gone to the wall now in -gen gcc.
Your recent generators are only passing one value so will not be affected by the possible 'bug' being looked at above.
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
The calling convention (stdcall, pascal, cdecl) imposes the order of passing the parameters (in the stack) relative to the order in which they are listed in the declaration, but nothing specifically imposes that the corresponding arguments are evaluated (for passing by value) in the same order.
Otherwise, I think gas(32) is right, and it is not because the arguments provided are references that they should not still be passed by value as stipulated in the declaration.
Otherwise, I think gas(32) is right, and it is not because the arguments provided are references that they should not still be passed by value as stipulated in the declaration.
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
The windows default must be stdcall because;
for ellipses you must write cdecl, so cdecl is not default
for my code to load left to right you must write pascal, so pascal is not the default.
deltarho
Never mind my byref generators gone to the wall with -gen gcc, it's out the window and over the hills and far away.
for ellipses you must write cdecl, so cdecl is not default
for my code to load left to right you must write pascal, so pascal is not the default.
deltarho
Never mind my byref generators gone to the wall with -gen gcc, it's out the window and over the hills and far away.
Code: Select all
Function rnd32(n as long=0) byref As Ulong
const k=2147483647
static as ulong z(1 to 5)={k,2,k,4,5}
if n=0 then
z(5) = z(1) - ((z(2) shl 27) or (z(2) shr (32 - 27)))
z(1) = z(2) xor ((z(3) shl 17) or (z(3) shr (32 - 17)))
z(2) = z(3) + z(4)
z(3) = z(4) + z(5)
z(4) = z(5) + z(1)
else
z(1)=k:z(2)=2:z(3)=k:z(5)=5
end if
return z(4)
End Function
sub seed32(n as ulong)
if n=0 then n=1
(rnd32(4))=n
rnd32
end sub
const k=2^32
#define range(f,l) clng((rnd32() mod (((l)-(f))+(1))) + (f))
#define frnd rnd32/k
seed32(20000)
screen 19,32
for n as long=1 to 20
circle(frnd*800,frnd*600),20+frnd*20,rgb(frnd*255,frnd*255,frnd*255),,,,f
next
dim as double lasts
for n as long=0 to 800
var s=abs(600-150*sin(n/500))
line(n,s)-(n,800),rgb(frnd*10,200+500*(s-lasts),frnd*10)
lasts=s
next
sleep
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
They are evaluated in the right order and used in the right order :fxm wrote: ↑Aug 15, 2024 11:33 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.
Code: Select all
gas32
-----
call RND2 (first parameter)
push on stack value from address1
call RND2 (second parameter)
push on stack value from address1
call RND2(third parameter)
push on stack value from address1
call TEST
Code: Select all
gas64/gcc
---------
call RND2 (first parameter)
store address1 to V1
call RND2 (second parameter)
store address1 to V2
call RND2 (third parameter)
store address1 to V3
use V1 to retrieve value first parameter but same like third parameter due to address1
use V2 to retrieve value second parameter but same like third parameter
use V3 to retrieve value third parameter
call TEST
-
- Posts: 4705
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
I doubt that the following is related to the issue currently being looked at, but it is related to a function returning a value ByRef.
Suppose we have:
Suppose we execute foo() = <whatever>
Foo() will be executed, but the value of Ret on entry will be zero.
The 'Do something according to the value of Ret' will be skipped if 'Ret = 0' is not considered. The 'Some code' will get executed, which could be a problem.
When we come to execute foo(), as in Print foo() for example, it is at that point that Ret will be equal to <whatever>.
To avoid any issues, we should consider 'Ret = 0' when we execute 'foo() = <whatever>'. If true, then we should exit foo() with 'Return Ret' without further ado. The <whatever> will bite when we execute foo() the first time.
Here is an example:
We get:
If we don't consider 'Ret = 0' we get:
Suppose we have:
Code: Select all
Function foo() ByRef As Long
Static As Long Ret
'Do something according to the value of Ret
'Some code
Return Ret
End Function
Foo() will be executed, but the value of Ret on entry will be zero.
The 'Do something according to the value of Ret' will be skipped if 'Ret = 0' is not considered. The 'Some code' will get executed, which could be a problem.
When we come to execute foo(), as in Print foo() for example, it is at that point that Ret will be equal to <whatever>.
To avoid any issues, we should consider 'Ret = 0' when we execute 'foo() = <whatever>'. If true, then we should exit foo() with 'Return Ret' without further ado. The <whatever> will bite when we execute foo() the first time.
Here is an example:
Code: Select all
Function foo1() ByRef As Long
Static Ret As long
Static SomeValue As Long
If Ret < 0 Then
Print "Initialize code"
Elseif Ret = 0 Then
Return Ret
End If
SomeValue+=1
Ret = SomeValue
Return Ret
End Function
foo1()=-1
Print foo1()
Print foo1()
Sleep
Code: Select all
Initialize code
1
2
Code: Select all
Initialize code
2
3
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
Like most things in fb, you can have a workaround.
For gcc we must have a different memory location each parameter call.
Maybe I can do the similar in a random generator for gcc, but it is all getting a little exasperating, so I'll leave it just now.
For gcc we must have a different memory location each parameter call.
Code: Select all
Function foo1() As Long Ptr
Static As Long x(0 To 100)
Static As Long somevalue,inc
Static Ret As Long Ptr
ret=@x(inc)
inc+=1
If inc>100 Then inc=0
SomeValue+=1
*Ret = SomeValue
Return Ret
End Function
Function foo2() As Long Ptr
Static As Long u
u+=1
Return @u
End Function
Print Chr(48+*foo1,48+*foo1,48+*foo1,48+*foo1,48+*foo1,48+*foo1,48+*foo1,48+*foo1,48+*foo1) 'OK in gas/gcc
Print Chr(48+*foo2,48+*foo2,48+*foo2,48+*foo2,48+*foo2,48+*foo2,48+*foo2,48+*foo2,48+*foo2) 'OK in gas
Sleep
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
New topic split from original What is randomize / rnd ?
fxm, thank-you for the bug report. Yes when days become shorter and nights colder I may have time again ...
I will post an example of a related behaviour on sf.net
----
My opinion is that if the code author's intent is clear and there are specific rules to follow the yes of course we should want predictable behaviour. Should be obvious that this is not what we currently have; returning references of functions with side effects on global state, plus c/c++ doesn't specify anything in standards about evaluation order. Not an expert, but I read c++17 begins to introduce some standards to enforce the sequencing of instructions, but I think is mainly related to chaining (e.g. object.method(args...).method(args...).etc) trying to ensure that the code author's intent is respected.
fxm, thank-you for the bug report. Yes when days become shorter and nights colder I may have time again ...
I will post an example of a related behaviour on sf.net
----
My opinion is that if the code author's intent is clear and there are specific rules to follow the yes of course we should want predictable behaviour. Should be obvious that this is not what we currently have; returning references of functions with side effects on global state, plus c/c++ doesn't specify anything in standards about evaluation order. Not an expert, but I read c++17 begins to introduce some standards to enforce the sequencing of instructions, but I think is mainly related to chaining (e.g. object.method(args...).method(args...).etc) trying to ensure that the code author's intent is respected.
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
I don't know about C++ 17 but both of the 'what fbc curretly does' and 'what fbc should probably do' in that sf post are done by C++ compilers now, so neither one is 'more' correct than the other. The a's have to be done in order but all that has to happen in respect of the d's is that the d happens before its corresponding a, so whether batched or interleaved they both fulfill that.
One could say, in C++ land at least, that if your code relies on either order, it's probably broken even if not technically broken by the letter of the law. Because who knows when your compiler will change it (Hey, whaddaya know, GCC before version 7 generates the current MSVC order, so it has changed in GCC at least once)
One could say, in C++ land at least, that if your code relies on either order, it's probably broken even if not technically broken by the letter of the law. Because who knows when your compiler will change it (Hey, whaddaya know, GCC before version 7 generates the current MSVC order, so it has changed in GCC at least once)
Code: Select all
T:\>cl /Ox /TP /Fe:testmsvc.exe test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:testmsvc.exe
test.obj
T:\>testmsvc.exe
Q.d(3)
Q.d(2)
Q.d(1)
Q.a(1)
Q.a(2)
Q.a(3)
T:\>g++ -o testgcc.exe test.cpp
T:\>testgcc
Q.d(1)
Q.a(1)
Q.d(2)
Q.a(2)
Q.d(3)
Q.a(3)
--
test.cpp
#include <stdio.h>
struct Q
{
float x;
int d(int arg)
{
printf("Q.d(%d)\n", arg);
return arg;
}
Q& a(int arg)
{
printf("Q.a(%d)\n", arg);
return *this;
}
};
int main()
{
Q t;
t.a( t.d(1) ).a( t.d(2) ).a( t.d(3) );
}
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
Using PASCAL, left to right parameter read, solves the order problem, but not the memory problem in -gen gcc.
Using adeyblue's c++
gives:
Code: Select all
type Q
x as single
declare function d( byval arg as single ) as single
declare function a pascal( byval arg as single ) byref as Q
declare constructor()
end type
constructor Q()
end constructor
function Q.d( byval arg as single ) as single
print "Q.d(" & arg & ")"
return arg
end function
function Q.a pascal( byval arg as single ) byref as Q
if arg then print "Q.a(" & arg & ")"
x+=1
return this
end function
var t = Q()
t.a( t.d(1) ).a( t.d(2) ).a( t.d(3) )
var temp=Q()
temp.x=48
(t.a(0))=temp 'byref function test
print chr( t.a(0).x,t.a(0).x,t.a(0).x,t.a(0).x,t.a(0).x,t.a(0).x,t.a(0).x,t.a(0).x,t.a(0).x)
sleep
Code: Select all
#include <stdio.h>
struct Q
{
float x;
int d(int arg)
{
printf("Q.d(%d)\n", arg);
return arg;
}
Q& a(int arg)
{
if (arg != 0) {printf("Q.a(%d)\n", arg);};
x+=1;
return *this;
}
};
int main()
{
#define z char(t.a(0).x)
Q t;
t.a( t.d(1) ).a( t.d(2) ).a( t.d(3) );
Q temp;
temp.x=48;
t.a(0)=temp; // testing byref behaviour
printf("%c%c%c%c%c%c%c%c%c",z,z,z,z,z,z,z,z,z);
}
Code: Select all
Q.d(1)
Q.a(1)
Q.d(2)
Q.a(2)
Q.d(3)
Q.a(3)
987654321
-
- Posts: 4705
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
@dodicat
I learned a few things in the 'What is randomize / rnd thread.'
The most important one was in sorting out a segmentation error. fxm spotted a weakness in my code, which I initially disagreed with.
So I came here and checked out your opening post.
It uses my code which produced a segmentation error.
I replaced that with my latest code shown here to save you time:
Do the same to see what you now get.
I doubt that the above will be of any assistance regarding the 'Argument evaluation order' but at least Rnd2 is now doing what it should have done.
I learned a few things in the 'What is randomize / rnd thread.'
The most important one was in sorting out a segmentation error. fxm spotted a weakness in my code, which I initially disagreed with.
So I came here and checked out your opening post.
It uses my code which produced a segmentation error.
I replaced that with my latest code shown here to save you time:
Code: Select all
Function Rnd2() ByRef As Double
Static As ULong seed_value
Static As Double d
If d = 0 Then ' first pass
Return d ' As assigned in main by Rnd2() = <whatever> and we do not fall through
ElseIf d<0 Then ' second pass
seed_value=-d ' and fall throgh
End If
' on third pass d > 0
seed_value = seed_value * 1664525 + 1013904223
d=seed_value/2^32
Return d
End Function
I doubt that the above will be of any assistance regarding the 'Argument evaluation order' but at least Rnd2 is now doing what it should have done.
-
- Posts: 4705
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
I get two blank screens with gas64.
Re: Argument evaluation order and byref (from: What is randomize / rnd ?)
As reported in a previous post there is a bug : optimization prevented converting 32bit memory/register
I fixed it. So you can try with this version :
https://users.freebasic-portal.de/sarg/fbc64_120.zip
Edit : that was another bug... Anyway fixed in this version.
Last edited by SARG on Aug 19, 2024 12:41, edited 2 times in total.