I need to compare if all items of a given array are the same.
For now, I have the following code:
Type
TD = array [0..1] of TDateTime;
var A: TD;
B: TD;
begin
A[0] := Date-1; A[1] := Date+1;
B[0] := Date-1; B[1] := Date+1;
if CompareMem(@A, @B, SizeOf(TD)) then
Showmessage('Equals')
else
Showmessage('Differ');
This is working fine but as CompareMem is written in assembly I'm not able (yet) to understand what it does.
Is CompareMem a valid way to do what I want? Also, I would like to know if will work to every data types like string, integer, etc.
This is not written in assembly... Comparing memory is valid if all the memory is filled with array items without gaps. Generally it would work if
1) All array memory is filled with data without gaps (gap may contain garbage and cause false negative).
1.1. this should be enforced by packed array
keyword, if compiler would not ignore it
1.2 this should happen if SizeOf(A[1]) is 2,4,8,16 etc
But you better cover this by unit tests using FillChar with different patterns - they would imitate garbage, then manual filling of array elements with matching values, then checking with CompareMem that elements wiped all the pre-filled garbage.
2) Array elements only contain simple value types, not reference types.
Char, integer, double, short string, fixed-size array or record made of those - are simple types.
All other strings, pointers, objects, interfaces, dynamic and open arrays - are merely pointers to the external data, and can not be compared "by memory"
You may read about http://docwiki.embarcadero.com/Libraries/XE2/en/System.Finalize for more hints. Assembler implementation of procedures/functions would also be good topic, as it would cover binary representations of different Delphi data types
CompareMem
simply performs a byte by byte comparison. There are two main ways in which CompareMem
fails to be valid for equality testing by value:
You are asking about arrays. Since arrays are always packed, they contain no padding. Since you are comparing the array values, the question can focus on the elements of the array.
Value comparison of arrays will be an appropriate thing to do if and only if the array elements are value types that contain no padding bytes and contain no reference types.
This is the case for all simple value types.
For records, you need to check whether or not the record contains reference types. This must be a recursive check. Does the record contain records that contain reference types, and so on. And then you must look for padding. As soon as you find padding, the use of CompareMem
is not appropriate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With