Reputation: 29
The following C code:
typedef unsigned char byte;
byte temp[8] = {...};
unsigned long iONE = 0;
unsigned long iTWO = 0;
memcpy(((byte *)&iONE)+sizeof(unsigned long)-4, temp, 4);
memcpy(((byte *)&iTWO)+sizeof(unsigned long)-4, temp+4, 4);
What is the significance of +sizeof(unsigned long)-4
?
Could the memcpy
statements be written as:
memcpy((byte *)&iONE, temp, 4);
memcpy((byte *)&iTWO, temp+4, 4);
And is the Delphi conversion valid:
var
temp: array[0..7] of Byte;
iONE: Cardinal;
iTWO: Cardinal;
begin
temp := ...;
iONE := 0;
iTWO := 0;
CopyMemory(iOne, temp[0], SizeOf(Cardinal));
CopyMemory(iTwo, temp[4], SizeOf(Cardinal));
end;
Upvotes: 0
Views: 324
Reputation: 612904
(byte *)&iONE)+sizeof(unsigned long)-4
is trying read 4 bytes from iONE
but also account for the possibility that unsigned long
is larger than 4 bytes. The code does so by picking off the last 4 bytes of iONE
. Since the code always reads from the same end of the variable its behaviour varies between little and big endian machines. Without any context it is hard to say what this code is trying to achieve but my guess is that it was originally running on a big endian system with 8 byte unsigned long
. Perhaps you know more.
In Delphi you'd probably write it like this.
var
temp: array[0..7] of Byte;
iONE: Cardinal;
iTWO: Cardinal;
begin
temp := ...;
iONE := PCardinal(@temp[0])^;
iTWO := PCardinal(@temp[4])^;;
end;
However, it would help to know more about the original code. Personally if I was faced with this task I'd write the code from scratch rather than make a literal port. The original code already looks poor and once it has been translated it will be even worse. Work out what the code does and write a new program using the idiom of the target language.
Two minor points on your code:
CopyMemory
is a Windows API function and as such not portable. System.Move
is the function to use for raw memory copies. Upvotes: 1
Reputation: 53006
memcpy(((byte *)&iONE)+sizeof(unsigned long)-4, temp, 4);
is copying 4 bytes from temp
into iONE
's address at offset sizeof(unsigned long)-4
, and
memcpy((byte *)&iONE, temp, 4);
will copy 4 bytes from temp
at the beginning of the address where iONE
is stored.
So sizeof(unsigned long)-4
is just an offset in bytes, at which to copy the 4 bytes from temp
.
Upvotes: 0