I need to double check my code. My build passed and migration test also
succeeded.


On 10/14/2016 04:07 AM, Paolo Bonzini wrote:
> 
> 
> On 14/10/2016 12:44, Dr. David Alan Gilbert wrote:
>>>> +#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                     
>>>>      \
>>>> +        *((void **) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFFSET)) = 
>>>> NULL;   \
>>>> +        *((void **) ((char *) (elm) + (entry) + QTAILQ_PREV_OFFSET)) =    
>>>>      \
>>>> +            *((void **) ((char *) (head) + QTAILQ_LAST_OFFSET));          
>>>>      \
>>>> +        **((void ***)((char *) (head) + QTAILQ_LAST_OFFSET)) = (elm);     
>>>>      \
>>>> +        *((void **) ((char *) (head) + QTAILQ_LAST_OFFSET)) =             
>>>>      \
>>>> +            (void *) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFFSET);     
>>>>      \
>>>> +} while (/*CONSTCOND*/0)
>> I wonder if there's a simpler way to do this; I'm not sure this works, but 
>> something like:
>>
>> struct QTAILQDummy {
>>     char dummy;
>> };
>>
>> QTAILQ_HEAD(QTAILQRawHead, struct QTAILQDummy)
>> typedef QTAILQ_ENTRY(struct QTAILQDummy) QTAILQRawEntry;
>>
>> #define QTAILQ_RAW_FOREACH(elm, head, entry)                                 
>>   \
>>         for ((elm) = ((struct QTAILQRawHead *)head)->tqh_first)              
>>   \
>>              (elm);                                                          
>>   \
>>              (elm) =                                                         
>>   \
>>              (elm) = ((QTAILQRawEntry *)((char *) (elm) + (entry)))->tqh_next
>>
>> and then I think elm gets declared as a struct QTAILQDummy.
>> But it does avoid those FIRST_OFFSET/LAST_OFFSET/NEXT_OFFSET/PREV_OFFSET 
>> calculations.
> 
> Another possibility is a macro like
> 
> #define field_at_offset(base, offset, type) \
>    ((type) (((char *) (base)) + (offset)))
> 
> so that you can do
> 
>    *field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET) = NULL;
>    *field_at_offset(void ***, elm, (entry) + QTAILQ_PREV_OFFSET) =
>        *field_at_offset(void ***, head, QTAILQ_LAST_OFFSET);
>    **field_at_offset(void ***, head, QTAILQ_LAST_OFFSET) = (elm);
>    *field_at_offset(void ***, head, QTAILQ_LAST_OFFSET) =
>         field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET);

The thing is that we don't know type at all. So only the offset values
is used. This is intended for QTAILQ of any type.

Thanks,
Jianjun

> 
> or something like that (note that I've always used the same type for
> next and last, by the way).
> 
> Paolo
> 


Reply via email to