[fpc-pascal] Translate C code

Karoly Balogh (Charlie/SGR) charlie at scenergy.dfmk.hu
Sat Jan 6 07:49:10 CET 2018


Hi,

On Sat, 6 Jan 2018, Darius Blaszyk wrote:

> Again I would like to ask some support on a piece C code that I need to
> translate to pascal. The code in question is:
>
> #define MEMNEXT(x) ((MyStruct *)(((char *) x) - ((char *) & (((MyStruct *)0)->next))))
>
> What exactly is going on here? Where does the result point to? It seems
> like it starts with the pointer x and subtracts the size of the offset
> of the beginning of MyStruct up to the "next" variable. At least that's
> what I think is happening.

Yes, it looks like it. It simply substracts the offset of the "next" field
from the value of X; This is a better solution than hardwiring the offset
of next, which could change depending on the target platform's structure
padding, or other reasons (and sometimes could be hard to calculate by
hand anyway).

> Does anyone has an idea how to translate this into working pascal code?

Well, not sure why one needs to do this abomination, without knowing the
data structure it operates on, but nevertheless, you can do the same in
Free Pascal, but you better turn the macro into a function:

type
  PMyStruct = ^TMyStruct;
  TMyStruct = record
    some, fields: integer;
    next: PMyStruct;
  end;

function MEMNEXT(x: Pointer): PMyStruct;
begin
  MEMNEXT:=PMyStruct(PByte(x)-PByte(@(PMyStruct(nil)^.next)));
end;

If this function is used often, you can mark it as inline; So the compiler
can inline it, whenever necessary. If you want to avoid pointermath for
whatever reason, the same works if you cast the pointers to PtrUInt
instead of a PByte.

If the input value of X is other than a pointer, you can either overloaded
methods, or define a var parameter without type, for example.

Charlie



More information about the fpc-pascal mailing list