Am Freitag, dem 10.07.2026 um 13:37 +0200 schrieb Jakub Jelinek: > On Thu, Jul 09, 2026 at 08:25:12PM +0200, Martin Uecker wrote: > > Am Dienstag, dem 07.07.2026 um 16:47 +0200 schrieb Jakub Jelinek: > > > Hi! > > > > > > As I wrote earlier, I'd like to see _BitInt I/O support in > > > *printf*/*scanf* and extending support of _BitInt in stdbit.h > > > in C2Y. > > > > > > For those I wrote drafts of possible C2Y papers: > > > https://jakubjelinek.github.io/wg14/va_arg_bitint.html > > > https://jakubjelinek.github.io/wg14/stdbit_bitint.html > > > > > > I'd appreciate any comments on this. > > > Haven't tried to acquire paper numbers for these yet. > > > > > > Jakub > > > > Looks already good to me. I noticed some minor editorial > > issues: > > > > In the paragraph before proposal there is some closing > > tag missing for <code> after _BitInt. > > > > In "Possible variants" there is a closing parenthesis > > missing in the last sentence and in the proposed wording > > > > 7.16.2.3 The va_arg_bitint macro > > > > there is a closing parenthesis missing in the description > > after _BitInt(N) > > Thanks, hopefully fixed now. > > > (Otherwise I still think that allowing a variably-modified > > _BitInt in va_arg would be more elegant, because we > > might also want _BitInt(*) for matching in _Generic) > > _BitInt(*) for _Generic looks fine. > > Accepting _BitInt(n) for va_arg second argument is more problematic. > va_arg expression has the type specified by the second argument, > so either _BitInt(n) where n is non-constant would need to be > allowed everywhere where _BitInt(N) with constant N is allowed, but > if it is also supposed to be used for the scanf case, i.e. > *va_arg (ap, _BitInt(n) *) = something;, it would need to be treated > not just as some simple VLA, but stores to it would need to be > again > if (n <= 8) *(_BitInt(8) [[gnu::noalias]] *) addr = something; > else if (n <= 16) *(_BitInt(16) [[gnu::noalias]] *) addr = something; > else if (n <= 32) *(_BitInt(32) [[gnu::noalias]] *) addr = something; > else if (n <= 64) *(_BitInt(64) [[gnu::noalias]] *) addr = something; > ... > else actual VLA-ish store; > and loads would need to be treated similarly. > Or, if _BitInt(n) would be only allowed in va_arg argument and > there would be some special case, say that va_arg in that case returns > _BitInt(BITINT_MAXWIDTH), then va_arg would work, although very > inefficiently if n is significantly smaller than BITINT_MAXWIDTH, and > there would be major other problems (GCC vs. Clang. vs other compilers > having different BITINT_MAXWIDTH, so C library would need to be > implemented using the compiler with the largest supported one in order > not to truncate bits, and the next decade or so transition problem > of being able to compile C library with older compiler), but how do > you handle the scanf case then? > > Implementation-wise, supporting the VLA _BitInt everywhere would be a > nightmare, in GCC the _BitInt lowering is around 300KiB of code and > having to deal with VLAs could significantly grow that.
I would not allow generic VLA-type _BitInt and only allow it va_arg and certain other scenarios. But how exactly would need to be worked out, e.g. using the va_arg_ptr we discussed previously void *bitintptr = va_arg_ptr(ap, _BitInt(n)); or by making the result of va_arg an lvalue void *bitintptr = &va_arg(ap, _BitInt(n)), 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 I am not against proceeding with your proposal now as it i. Martin > > Jakub
