Porting C macro

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Porting C macro

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

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Porting C macro

etrusco
On 3/11/13, Darius Blaszyk <[hidden email]> 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))))
>
> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Porting C macro

Henry Vermaak
In reply to this post by Darius Blaszyk
On Mon, Mar 11, 2013 at 11:26:57PM +0100, 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Porting C macro

Darius Blaszyk

Henry Vermaak schreef op 12 mrt '13:

On Mon, Mar 11, 2013 at 11:26:57PM +0100, 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

I will let your email sink in later, but here is a usage example as requested

  if (list->next) GETNEXT(list->prev)->nextname = GETNEXT(list->next)->name;
  else GETNEXT(list->prev)->nextname = 0;

Both name and nextname are pchar's.

Regards, Darius


 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Porting C macro

Darius Blaszyk
In reply to this post by Henry Vermaak

Henry Vermaak schreef op 12 mrt '13:

On Mon, Mar 11, 2013 at 11:26:57PM +0100, 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

BTW, you were right. The ^ was indeed a ->, but got replaced in the porting process.

Regards, Darius


 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Porting C macro

Darius Blaszyk
In reply to this post by etrusco

Flávio Etrusco schreef op 12 mrt '13:

On 3/11/13, Darius Blaszyk <[hidden email]> 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)))) 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Porting C macro

etrusco
On Tue, Mar 12, 2013 at 5:30 AM, Darius Blaszyk
<[hidden email]> wrote:

> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal