0

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;
3
  • Ask yourself what this does on a platform where sizeof(unsigned long) is greater than 4 octets (think 8, then do the math). You may also consider the ramifications of running this on a big-vs-little endian system. Commented Jan 25, 2015 at 0:57
  • 1
    Let's get serious. This is horrible, non portable code, and it's not possible to tell without context, what "the significance" of those operations should be. The code seems to make assumptions about endianess and sizeof(unsigned long), that at least I am not able to decipher in purpose. Commented Jan 25, 2015 at 1:03
  • It is little endian system (Windows). And the unsigned long is 4 bytes. Not sure if I answered the question. Commented Jan 25, 2015 at 20:46

2 Answers 2

1
(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:

  1. It is pointless to initialise a variable that is immediately over-written. That just confuses the future reader.
  2. CopyMemory is a Windows API function and as such not portable. System.Move is the function to use for raw memory copies.
Sign up to request clarification or add additional context in comments.

6 Comments

Your comment very useful. Thank you for the succinct Delphi code.
I deleted the post to avoid straying. Will post as new question at the right time. Thank you for your comment.
What about this question?
Thank you David. The C code is likely not original. The intended unsigned long is 4 bytes (Windows). The temp[8] is big endian, and holds IBM doubles that needs to be converted into IEEE double (little endian). iONE and iTWO are bytes swapped before further manipulation.
I mean, I think this question has been answered
|
0
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.

2 Comments

While this is technically correct, that doesn't tell anything about the significance :-P ...
Your comment helpful. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.