Page 2 of 3

Posted: Thu Feb 09, 2006 8:34 pm
by freedimension
Yep, seems you're right.

Code: Select all

a.s = "12345678"
CopyMemory(@a, @a+2, 4)
Debug a

a.s = "12345678"
MoveMemory(@a, @a+2, 4)
Debug a

Debug "--------"

a.s = "12345678"
CopyMemory(@a+2, @a, 4)
Debug a

a.s = "12345678"
MoveMemory(@a+2, @a, 4)
Debug a
Fred, how are those two commands implemented? Normally CopyMemory should be a little bit faster, but also more unstable because it hasn't to look for overlapping memory adresses.

This makes me somewhat responsible as it was my idea to introduce MoveMemory :oops:

Posted: Thu Feb 09, 2006 8:43 pm
by Trond
:lol:


I just read in the help file for Windows API and it said that the results of CopyMemory were undefined when the memory blocks overlap and that MoveMemory didn't have this "problem". However they do seem to work the same.

Posted: Thu Feb 09, 2006 9:06 pm
by freak
Well, just because the behaviour is undefined does not mean it _has_ to fail ;)

They both wrap directly the api calls (which as i have just seen are defined as
memcpy() and memmove() in the headers.)

I would guess that it maybe makes a difference for copying/moving larger areas of memory. (not sure though)
All documentation states that memcpy()/CopyMemory() is unsafe to use with
overlapping buffers, so there has to be something to it.

Posted: Thu Feb 09, 2006 9:17 pm
by Trond
Do not believe everything that is true.

Posted: Thu Feb 09, 2006 9:27 pm
by netmaestro
I find the path of least resistance to be = doing it Fred's way.

Posted: Thu Feb 09, 2006 10:37 pm
by freedimension
At least here, they seem to be the same:

Code: Select all

s1.s = ""

For x=1 To 20000
  s1 + Chr(Random(25)+65)
Next

s2.s = s1.s


t1 = ElapsedMilliseconds()
For i = 0 To 1000000
  CopyMemory(@s1 + 9900, @s1, 9900)
Next
t2 = ElapsedMilliseconds()
For i = 0 To 1000000
  MoveMemory(@s2 + 9900, @s2, 9900)
Next
t3 = ElapsedMilliseconds()

OpenConsole()

If s1 = s2
  PrintN("Gleich")
Else
  PrintN("Ungleich")
EndIf

PrintN("1. " + Str(t2 - t1))
PrintN("2. " + Str(t3 - t2))

Input() 
CloseConsole()
Though that doesn't mean nothing, another OS - even another Windows - might bring a surprise.

Posted: Thu Feb 09, 2006 11:27 pm
by Fred
freedimension wrote:Though that doesn't mean nothing, another OS - even another Windows - might bring a surprise.
That's the whole point.

Posted: Fri Feb 10, 2006 4:41 pm
by Trond
Fred wrote:
freedimension wrote:Though that doesn't mean nothing, another OS - even another Windows - might bring a surprise.
That's the whole point.
Not really, since it's the same function on all Windowes. MoveMemory() and CopyMemory() aren't in Windows, they are both macros for functions in the standard c libraries. Once compiled and working it should work everywhere.

Posted: Fri Feb 10, 2006 5:46 pm
by Fred
freedimension wrote:Though that doesn't mean nothing, another OS - even another Windows - might bring a surprise.

Posted: Tue Feb 14, 2006 10:28 am
by netmaestro
I GOT IT!! I devised a plan to write a command that accurately returns the data type of a variable. It's partly tested and working so far, I just have to put it through the wringer before showing it off. When it's finished I'll post.

Posted: Tue Feb 14, 2006 3:21 pm
by Trond
netmaestro wrote:I GOT IT!! I devised a plan to write a command that accurately returns the data type of a variable. It's partly tested and working so far, I just have to put it through the wringer before showing it off. When it's finished I'll post.
That's impossible unless you carry with you some pre-execute information under the table.

Posted: Tue Feb 14, 2006 4:30 pm
by netmaestro
As promised, for numeric types here goes:

Code: Select all

Macro GetTypeOf(x,y) 
  *sto=AllocateMemory(SizeOf(x)) 
  CopyMemory(@x,*sto,SizeOf(x)) 
  x=1 
  If PeekQ(@x) = x And SizeOf(x) = 8 
    y="Quad" 
  ElseIf PeekL(@x) = x And SizeOf(x) = 4 
    y="Long" 
  ElseIf PeekF(@x) = x And SizeOf(x) = 4 
    y="Float" 
  ElseIf PeekD(@x) = x And SizeOf(x) = 8 
    y="Double" 
  ElseIf PeekW(@x) = x And SizeOf(x) = 2 
    y="Word" 
  ElseIf PeekB(@x) = x And SizeOf(x) = 1 
    y="Byte" 
  EndIf 
  CopyMemory(*sto,@x,SizeOf(x)) 
EndMacro 
  
a.l 
b.q 
c.f 
d.d 
e.w 
f.b 


LastType.s = ""  ;store the result here 
GetTypeOf(a,LastType) 
Debug LastType 
GetTypeOf(b,LastType) 
Debug LastType 
GetTypeOf(c,LastType) 
Debug LastType 
GetTypeOf(d,LastType) 
Debug LastType 
GetTypeOf(e,LastType) 
Debug LastType 
GetTypeOf(f,LastType) 
Debug LastType 

Posted: Tue Feb 14, 2006 4:34 pm
by Dare2
:D

Regardless of whether it should work or not, pretty nifty!

Posted: Tue Feb 14, 2006 7:17 pm
by Trond
netmaestro wrote:As promised, for numeric types, here goes:
Only numeric types? That's cheating. Besides:
1. You use SizeOf() which is not a run-time function, it's result is determined at compile time (look at the generated assembly code).
2. It doesn't work. Huh? Look at this:

Code: Select all

Macro GetTypeOf(x,y) 
  *sto=AllocateMemory(SizeOf(x)) 
  CopyMemory(@x,*sto,SizeOf(x)) 
  x=1 
  If PeekQ(@x) = x And SizeOf(x) = 8 
    y="Quad" 
  ElseIf PeekL(@x) = x And SizeOf(x) = 4 
    y="Long" 
  ElseIf PeekF(@x) = x And SizeOf(x) = 4 
    y="Float" 
  ElseIf PeekD(@x) = x And SizeOf(x) = 8 
    y="Double" 
  ElseIf PeekW(@x) = x And SizeOf(x) = 2 
    y="Word" 
  ElseIf PeekB(@x) = x And SizeOf(x) = 1 
    y="Byte" 
  EndIf 
  CopyMemory(*sto,@x,SizeOf(x)) 
EndMacro 
  
a.l 
b.q 
c.f 
d.d 
e.w 
f.b 
g.c ;)

LastType.s = ""  ;store the result here 
GetTypeOf(a,LastType) 
Debug LastType 
GetTypeOf(b,LastType) 
Debug LastType 
GetTypeOf(c,LastType) 
Debug LastType 
GetTypeOf(d,LastType) 
Debug LastType 
GetTypeOf(e,LastType) 
Debug LastType 
GetTypeOf(f,LastType) 
Debug LastType
GetTypeOf(g,LastType) ;)
Debug LastType

Posted: Tue Feb 14, 2006 10:23 pm
by netmaestro
And for chars included:

Code: Select all

Macro GetTypeOf(x,y) 
  *sto=AllocateMemory(SizeOf(x)) 
  CopyMemory(@x,*sto,SizeOf(x)) 
  x=1 
  If PeekQ(@x) = x And SizeOf(x) = 8 
    y="Quad" 
  ElseIf PeekL(@x) = x And SizeOf(x) = 4 
    y="Long" 
  ElseIf PeekF(@x) = x And SizeOf(x) = 4 
    y="Float" 
  ElseIf PeekD(@x) = x And SizeOf(x) = 8 
    y="Double" 
  ElseIf PeekW(@x) = x And SizeOf(x) = 2 
    y="Word" 
  ElseIf PeekB(@x) = x And SizeOf(x) = 1 
    y="Byte"
    x=255
    If x = 255 ; a byte type will fail this test 
      y="Char" 
    EndIf
  EndIf 
  CopyMemory(*sto,@x,SizeOf(x)) 
EndMacro 
  
a.l 
b.q 
c.f 
d.d 
e.w 
f.b 
g.c  

LastType.s = ""  ;store the result here 
GetTypeOf(a,LastType) 
Debug LastType 
GetTypeOf(b,LastType) 
Debug LastType 
GetTypeOf(c,LastType) 
Debug LastType 
GetTypeOf(d,LastType) 
Debug LastType 
GetTypeOf(e,LastType) 
Debug LastType 
GetTypeOf(f,LastType) 
Debug LastType 
GetTypeOf(g,LastType) ;) 
Debug LastType