Jamie Lokier <ja...@shareable.org> wrote: > Juan Quintela wrote: >> * add VARRAY_UINT16_UNSAFE: unsafe here means that type checking is off >> (a.k.a. as a cast in C). In this case the problem is that the last >> element of one struct is int foo[0], and we allocate the right size >> for the array we want. Problem? I haven't been able to abuse^Wuse >> gcc + cpp + magic to typecheck that for vmstate: >> >> We have >> struct FOO { >> int32_t foo[0]; >> } >> We want to "compare the type of foo (t1) with int32_t (t2) >> >> ((t1(*)[n])0 - (t2*)0) >> This one don't work, because we don't have 'n' >> ((t1(**))0 - (t2*)0) >> This don't work either because t1 is one array. >> ((t1(*)[])0 - (t2*)0) >> Too clever, imposible cast to on array type. >> I tried some other variants, but have not able to get one that compiles. > > Since you mention GCC, is it ok to use GCC extensions?
I would bet that qemu don't compile with anyother compiler without big changes :) > __typeof__(t1) > often does the trick for this sort of thing where t1 alone does not > compile, even if t1 is a type. > > __builtin_types_compatible_p(), __builtin_choose_exper and > __attribute__((__error__)) are good for informative error messages. Thanks, will take a look. 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’) And at this point, I got confused :( After reading the info of __builtin_types_compatible_p(), it could perhas be useful. Thinking and testing a bit more about it. Later, Juan.