Hi, Martin,

Looks like that there is some issue when I tried to use the _Generic for the 
testing cases, and then I narrowed down to a
small testing case that shows the problem without any change to GCC.

[opc@qinzhao-ol8u3-x86 gcc]$ cat t1.c
struct annotated {
  char b;
  int c[];
} *array_annotated;  
extern void * counted_by_ref (int *);

int main(int argc, char *argv[])
{
  typeof(counted_by_ref (array_annotated->c)) ret
    = counted_by_ref (array_annotated->c); 
   _Generic (ret, void* : (void)0, default: *ret = 10);

  return 0;
}
[opc@qinzhao-ol8u3-x86 gcc]$ /home/opc/Install/latest/bin/gcc t1.c
t1.c: In function ‘main’:
t1.c:12:44: warning: dereferencing ‘void *’ pointer
   12 |   _Generic (ret, void* : (void)0, default: *ret = 10);
      |                                            ^~~~
t1.c:12:49: error: invalid use of void expression
   12 |   _Generic (ret, void* : (void)0, default: *ret = 10);
      |                                                 ^

Actually, I debugged this issue into gcc’s C routine 
“c_parser_generic_selection”.
And found that, the “default” branch of the _Generic is always parsed even 
though there is already
a match in the previous conditions. Therefore, *ret = 10 is parsed even when 
ret is a void *, therefore the compilation error.

So, I am not sure whether this is the correct behavior of the operator 
_Generic? 
Or is there any obvious error in the above small testing case?
If So, then looks like that we cannot use the _Generic operator for this 
purpose.

Any comments on this?

Thanks a lot for your help.

Qing


> On Aug 21, 2024, at 11:43, Martin Uecker <uec...@tugraz.at> wrote:
> 
> Am Mittwoch, dem 21.08.2024 um 15:24 +0000 schrieb Qing Zhao:
>>> 
>>> But if we changed it to return a void pointer,  we could make this
>>> a compile-time check:
>>> 
>>> auto ret = __builtin_get_counted_by(__p->FAM);
>>> 
>>> _Generic(ret, void*: (void)0, default: *ret = COUNT);
>> 
>> Is there any benefit to return a void pointer than a SIZE_T pointer for
>> the NULL pointer?
> 
> Yes! You can test with _Generic (or __builtin_types_compatible_p)
> at compile-time based on the type whether you can set *ret to COUNT
> or not as in the example above.
> 
> So it is not a weird run-time test which needs to be optimized
> away.
> 

Reply via email to