Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: _BitInt(N) Date: Sun, 23 Nov 2025 14:38:17 -0800 Organization: None to speak of Lines: 88 Message-ID: <87ms4c4bom.fsf@example.invalid> References: <10dajlh$ko3c$1@dont-email.me> <10fus62$hl69$1@solani.org> <10fv2dm$3can9$1@paganini.bofh.team> <10fv40v$1f7a2$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Sun, 23 Nov 2025 22:38:29 +0000 (UTC) Injection-Info: dont-email.me; posting-host="f1a645414c354994bf497b1d68dea44c"; logging-data="1981385"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX183S/yGPWrfs8yB+2TvrrrX" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:/mcWw/LY4CYwas2pAUnOQ1YhhnI= sha1:PhsroVdTXnru8up7H8so71e70Sk= Xref: csiph.com comp.lang.c:395395 bart writes: > On 23/11/2025 13:32, Waldek Hebisch wrote: >> Philipp Klaus Krause wrote: >>> Am 22.10.25 um 14:45 schrieb Thiago Adams: >>>> Is anyone using or planning to use this new C23 feature? >>>> What could be the motivation? >>> >>> Saving memory by using the smallest multiple-of-8 N that will do. >> IIUC nothing in the standard says that it is smallest multiple-of-8. >> Using gcc-15.1 on AMD-64 is get 'sizeof(_BitInt(22))' equal to 4, >> while the number cound fit in 3 bytes. > > The rationale mentions a use-case where there is a custom processor > that might actually have a 22-bit hardware types. What rationale are you referring to? There hasn't been an official ISO C Rationale document since C99. > Implementing such odd-size types on regular 8/16/32/64-bit hardware is > full of problems if you want to do it without padding (in order to get > the savings). On even with padding (to get the desired overflow > semantics). > > Such as working out how pointers to them will work. Why would pointers to _BitInt types be a problem? A _BitInt object is a fixed-size chunk of memory, similar to a struct object. >>> Also being able to use bit-fields wider than int. >> For me main gain is reasonably standard syntax for integers bigger >> that 64 bits. > > Standard syntax I guess would be something like int128_t and > int256_t. Such wider integers tend to be powers of two. > > But there are two problems with _BitInt: > > * Any odd sizes are allowed, such as _BitInt(391) Why is that a problem? If you don't want odd-sized types, don't use them. > * There appears to be no upper limit on size, so _BitInt(2997901) is a > valid type The upper limit is specified by the implementation as BITINT_MAXWIDTH, a macro defined in . For gcc 15.2.0 on x86_64, BITINT_MAXWIDTH is 65535 (2**16-1). For clang 21.1.5 it's 8388608 (2**23 bits, 1048576 bytes). clang seems to have some problems with _BitInt(8388608). For example, this program: #include _BitInt(BITINT_MAXWIDTH) n = 42; int main(void) { n *= n; } takes a *long* time to compile with clang. I believe it's generating inline code to do the 8388608 by 8388608 bit multiplication. > So what is the result type of multiplying values of those two types? _BitInt types are exempt from the integer promotion rules (so _BitInt(3) doesn't promote to int), but the usual arithmetic conversions apply. If you multiply values of two _BitInt types, the result is the wider of the two types. N3220 is a draft of C23. https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf > Integer sizes greater than 1K or 2K bits should use an arbitrary > precision type (which is how large _BitInts will likely be implemented > anyway), where the precision is a runtime attribute. _BitInt(n) objects are fixed-size. Addition and subtraction should be fairly straightforward. For multiplication and division, gcc generates calls to __mulbitint3 and __divmodbitint4, and clang generates huge amounts of inline code. My guess is that future llvm/clang releases will handle _BitInt types more efficiently. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */