Am Freitag, dem 10.07.2026 um 15:08 +0200 schrieb Jakub Jelinek via Gcc:
> On Fri, Jul 10, 2026 at 02:54:38PM +0200, Martin Uecker wrote:
> > > If va_list is void */char *, then all ... arguments are passed
> > > on the stack and so the pointed to object will have the lifetime
> > > of the whole function.  But if the ABI needs to store some of
> > > the hard registers used for argument passing somewhere somewhere
> > > into the stack, and especially if ABI allows partial passing of
> > > _BitInt (say first word or two passed in registers, rest on the stack),
> > > then one actually doesn't have a contiguous chunk of memory that contains
> > > it, so va_arg_ptr or &va_arg would effectively need to create a temporary
> > > which holds the whole value.  
> > 
> > On the other hand, for large _BitInts one might avoid
> > unnecessary copies *if* it is continuously on the stack.
> 
> In the posted GCC patch, there is no copying under the hood (while the
> proposed wording in the paper draft suggests copying happens, it is not
> observable in any way).

Yes, but I am wondering whether we could this make more
useful also for users beyond supporting C libraries in implementing 
format strings and then avoiding copies for large _BitInts
may be a concern.

> 
> > Are there ABIs that do this differently?
> 
> I don't know, that is to be determined.  On x86/x86_64 no copying is needed
> for sure.
> Though, all the GCC target va_arg gimplification hooks return a MEM_REF, so
> the va_arg result is in all cases just a deference of some pointer.  Whether
> that pointer can be dereferenced e.g. after next va_arg is yet to be
> determined (and not needed in the proposed macros).
> 
> > > Now, if everything is hidden under a single
> > > macro, it is an implementation detail, but when it is exposed, for how 
> > > long
> > > that temporary is in scope?
> > 
> > Maybe it could just the block as if the va_arg creates
> > a compound literals.   I understand your argument though.
> > 
> > > 
> > > > One could also possibly allow them in pointer types
> > > > 
> > > > _BitInt(n) *ptr = va_arg(ap, _BitInt(n)*);
> > > > 
> > > > 
> > > > All this seems relatively unproblematic to me and would essentially
> > > > be just nicer syntax and better type safety for what you are proposing.
> > > 
> > > But then the question is if one can dereference *ptr or just pass it to
> > > some macro/function to decode it.
> > 
> > If one allows dereferencing it in general than one ends up
> > with lvalues of variable _BitInt type.  While I think this
> > would be useful, this would certainly make things a lot more
> > complicated.   But even without beind allowed to dereference
> > it, I think this would be useful because one could copy it
> > generically.
> > 
> > _BitInt(n) *ptr = va_arg(ap, typeof(ptr));
> > 
> > char buf[sizeof *ptr]
> > memcpy(buf, ptr, sizeof *buf);
> > 
> > or something like this.  Perhaps one could also allow dereferencing
> > on the RHS of an assignment.
> 
> To implement printf/scanf with _BitInt(n) support, we can't just memcpy
> it around, we need to decode/encode it to something that e.g. GMP or
> hand written code can deal with (and ideally shouldn't depend on the
> implementation details how is a _BitInt(N) laid out for the particular N).
> That encoding/decoding can be to/from _BitInt(BITINT_MAXWIDTH) if we don't
> mind it being inefficient and in the clang case maybe running out of stack
> (~1MiB; in gcc case 8KiB), or array of limbs the paper is proposing.

I agree that the encoding/decoding into an array of limbs is what
is needed for this purpose, but I am thinking more generally.  
Users may also want to pass generic _BitInts around. 

Martin


Reply via email to