I've been developing some software in Delphi 5 using DUnit as a driver for TDD but I found that when using CheckEqualsMem it kept failing even though in the debugger I could see that the objects being compared (two arrays of longwords in this case) were identical.
Internally, CheckEqualsMem uses CompareMem and found that this was what was returning false.
Delving a bit deeper I found that if I call CompareMem with a pointer to the address of the objects using @ or Addr CompareMem fails even when the memory is identical, but if I use PByte (from windows) or PChar it will compare the memory properly.
Why?
Here is an example
var
s1 : String;
s2 : String;
begin
s1 := 'test';
s2 := 'tesx';
// This correctly compares the first byte and does not return false
// since both strings have in their first position
if CompareMem(PByte(s1), PByte(s2), 1) = False then
Assert(False, 'Memory not equal');
// This however fails ?? What I think I am doing is passing a pointer
// to the address of the memory where the variable is and telling CompareMem
// to compare the first byte, but I must be misunderstanding something
if CompareMem(@s1,@s2,1) = False then
Assert(False,'Memory not equal');
// Using this syntax correctly fails when the objects are different in memory
// in this case the 4th byte is not equal between the strings and CompareMem
// now correctly fails
if CompareMem(PByte(s1),PByte(s2),4) = False then
Assert(False, 'Memory not equal');
end;
As you can see in the comments, I come from a C background, so I thought that @s1 is a pointer to the first byte of s1 and PByte(s1) should be the same thing, but its not.
What am I misunderstanding here? What is the difference between @ / Addr and PByte ??
@operator andAddrfunction are equal in meaning :Address of. Just to make that clear (if there was a doubt). There is also a note in documentation:Note: Addr is equivalent to the @ operator except that it is unaffected by the $T compiler directive. - LU RD