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