Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-03

Porting C macro

7 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Darius Blaszyk

I'm stuck porting a macro from C. Below is the original define. The part I'm struggeling with is the right most part after the - sign.

#define GETNEXT(x) ((LList *)(((char *) x) - ((char *) & (((LList *)0)^.next))))

Does anyone know what is meant with the define?
Obviously LList is a linked list struct that has a prev and next variable. But what does the & and 0 mean?

Appreciate any
help.

Regards, Darius

Flávio Etrusco
to Darius Blaszyk
Darius Blaszyk wrote 17 lines
I'm stuck porting a macro from C. Below is the original define. The part I'm struggeling with is the right most part after the - sign. #define GETNEXT(x) ((LList *)(((char *) x) - ((char *) & (((LList *)0)^.next)))) Does anyone know what is meant with the define? Obviously LList is a linked list struct that has a prev and next variable. But what does the & and 0 mean? Appreciate any help. Regards, Darius

AFAICS they mean "address" and "nil", respectively, so that part will return the offset of "next" inside and item of LList.

-Flávio

-Flávio

Henry Vermaak
to Darius Blaszyk: I'm stuck porting a macro from C. Below is the original define. The part I'm struggeling…
Darius Blaszyk wrote 8 lines
I'm stuck porting a macro from C. Below is the original define. The part I'm struggeling with is the right most part after the - sign. #define GETNEXT(x) ((LList *)(((char *) x) - ((char *) & (((LList *)0)^.next))))

I'm assuming that the "^." should be "->", in which case the last bit is doing the same as the offsetof() macro. So the macro is subtracting the offset in bytes of the "next" member of the LList struct from x, then casting it to (LList *).

I'd wager that the GETNEXT() isn't actually doing what it says, but something more like container_of() (because it's _subtracting_ the offset). I may be wrong, though, do you have an example of its usage?

Henry

Darius Blaszyk
to Henry Vermaak

Henry Vermaak schreef op 12 mrt '13:

On Mon, Mar 11, 2013 at
Darius Blaszyk wrote
> I'm stuck porting a macro

from C. Below is the original define. The part I'm struggeling with is the right most part after the - sign. #define GETNEXT(x) ((LList *)(((char *) x) - ((char *) & (((LList *)0)^.next))))

I'm assuming

that the "^." should be "->", in which case the last bit is

doing the

same as the offsetof() macro. So the macro is subtracting the

offset

in bytes of the "next" member of the LList struct from x, then

casting

it to (LList *).

I'd wager that the GETNEXT() isn't actually doing

what it says, but

something more like container_of() (because it's

_subtracting_ the

offset). I may be wrong, though, do you have an

example of its usage?

Henry
Darius Blaszyk
to Henry Vermaak: I'm assuming that the "^." should be "->", in which case the last bit is doing the same…

Henry Vermaak schreef op 12 mrt '13:

On Mon, Mar 11, 2013 at
Darius Blaszyk wrote
> I'm stuck porting a macro

from C. Below is the original define. The part I'm struggeling with is the right most part after the - sign. #define GETNEXT(x) ((LList *)(((char *) x) - ((char *) & (((LList *)0)^.next))))

I'm assuming

that the "^." should be "->", in which case the last bit is

doing the

same as the offsetof() macro. So the macro is subtracting the

offset

in bytes of the "next" member of the LList struct from x, then

casting

it to (LList *).

I'd wager that the GETNEXT() isn't actually doing

what it says, but

something more like container_of() (because it's

_subtracting_ the

offset). I may be wrong, though, do you have an

example of its usage?

Henry
Darius Blaszyk
to Flávio Etrusco: AFAICS they mean "address" and "nil", respectively, so that part will return the offset…

Flávio Etrusco schreef op 12 mrt '13:

On 3/11/13, Darius Blaszyk
> I'm stuck porting a macro from

C. Below is the original define. The part I'm struggeling with is the right most part after the - sign. #define GETNEXT(x) ((LList *)(((char *) x) - ((char *) & (((LList *)0)^.next)))) Does anyone know what is meant with the define? Obviously LList is a linked list struct that has a prev and next variable. But what does the & and 0 mean? Appreciate any help. Regards, Darius

AFAICS they mean "address" and "nil",

respectively, so that part will

return the offset of "next" inside and

item of LList.

-Flávio

So here is what I made based on your and
Henry's mail. However still it does not seem to work, although other ported code might be at fault of course :)

//#define GETNEXT(x) ((LList
*)(((char *) x) - ((char *) & (((LList *)0)->.next))))
function
GETNEXT(x: pLList): pLList; inline;
begin
 exit(pLList(pchar(x) -
pchar(pLList(nil)^.next)));
end;

And let LList be declared as:

LList
= record
 len: integer;
 next, prev: pLList;
 name: PChar;
 nextname:
PChar;
 flag: integer;
end;
Then I still don't understand what this
does:
 if list^.next  nil then
 list^.nextname :=
GETNEXT(list^.next)^.name;

Regards, Darius

Flávio Etrusco
to Darius Blaszyk
Darius Blaszyk wrote 14 lines
function GETNEXT(x: pLList): pLList; inline; begin exit(pLList(pchar(x) - pchar(pLList(nil)^.next))); end; And let LList be declared as: LList = record len: integer; next, prev: pLList; name: PChar; nextname: PChar; flag: integer; end;

AFAICS you're missing an "address" operator:
@(pLList(nil)^.next)

Otherwise you decrement by 'next' value - which I hope is zero ;-)

-Flávio