On Mon, Sep 09, 2024 at 02:10:05PM +0000, Qing Zhao wrote: > Okay, now after finishing reading all the discussion so far, I realized that > we are back to the previous pointer approach: > > __builtin_get_counted_by (p->FAM) > > Works as: > > If (has_counted_by (p->FAM)) > return &p->COUNT; > else > return (void *)0; > > Then the user will use it as: > > auto p = __builtin_get_counted_by(__p->FAM) > *_Generic(p, void*: &(int){}, default: p) = COUNT; > > The major reason for back to the previous pointer approach is (from Martin): > > "The initial proposal already has this as "Alternative Design" > and then there is this response to my comment: > > https://discourse.llvm.org/t/rfc-introducing-new-clang-builtin-builtin-get-counted-by/80836/27 > > which seems to imply that she is open to this idea.
I'd strongly prefer the pointer variant over some ugly hack like what is proposed for the returning lvalue case. Yes, returning various different pointer types is still not a normal builtin, but it is in line with various overloaded builtins where the return type depends on the argument types or other details, like __atomic_{load,exchange,compare_exchage} etc. clang with -fbounds-safety can impose some restrictions like that the pointer shouldn't escape the current function and be just dereferenced and not say cast to integer etc. If they "return lvalue", what prevents &__builtin_whatever (p->FAM)? And I still don't understand how they can avoid taking the address of the counter, can't one bypass that by say (int *) ((char *)&obj + offsetof (struct something, obj)) ? Jakub