Juan Quintela wrote:
> I have good error messages, I don't have good ideas about how to trick
> the compiler. Error messages are clear.
>
> Example:
>
> struct FOO {
> unt16_t foo[0];
> }
> #define vmstate_offset_pointer(_state, _field, _type) \
> (offsetof(_state, _field) + \
> type_check_pointer(_type, typeof_field(_state, _field)))
>
> Called with (after doing substitutions)
> type_check_pointer(uint16_t, struct FOO, foo);
>
> Give that, we try several definitions for type_check_pointer:
>
> #define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0)
>
> Gives the following error:
>
> /scratch/qemu/hw/eeprom93xx.c:144: error: invalid operands to binary -
> (have ‘uint16_t **’ and ‘uint16_t (*)[]’)
>
> Another try:
>
> #define type_check_pointer(t1,t2) ((t1(*)[])0 - (t2*)0)
>
> gives
>
> /scratch/qemu/hw/eeprom93xx.c:148: error: arithmetic on pointer to an
> incomplete type
>
> Another one:
>
> #define type_check_pointer(t1,t2) ((t1(*)[0])0 - (t2*)0)
>
> gives:
>
> /scratch/qemu/hw/eeprom93xx.c:151: error: initializer element is not constant
> /scratch/qemu/hw/eeprom93xx.c:151: error: (near initialization for
> ‘vmstate_eeprom’)
#define type_check_pointer(t1,t2) (0*sizeof((t1(*)[0])0 - (t2*)0))
Or if you want foo[] to work:
#define type_check_pointer(t1,t2) (0*sizeof((t1(**)[])0 - (t2**)0))
Dubiously, but fortunately, the second one works with foo[] and foo[0]
in GCC.
Enjoy :-)
-- Jamie