Jamie Lokier <[email protected]> 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.