Date: Mon, 1 Sep 2025 21:14:24 +0200
> The first question I have with something like `_BitInt(N)` is... how
> does `N` work? `bit_int<N>` works in a way that we understand in C++
> because... it's a template. It looks like a type generated via a
> template. `_BitInt(N)` looks like a function call. For `bit_int<N>`,
> `N` is a template argument. Therefore it must be a constant
> expression.
Well, how does N work in int[N]? The answer is that you don't really
have to know if you just use std::array<int, N> and don't get in touch
with these mechanisms inherited from C. So to answer your question,
don't ask, just use std::bit_int<N>. The alias template should
definitely be the one taught to new C++ developers.
> But for `_BitInt(N)`... what is `N` allowed to be? C++ does have
> `consteval` functions that forbid taking non-constant expression
> parameters, but `_BitInt` is *not* a function call. It's a thing that
> looks like a function call that results in a type? While C++ may
> eventually have something like that post-reflection, it's not a normal
> C++ thing right now.
I don't think _BitInt is any less usual than static_assert or
delete("reason") or sizeof or typeof or alignas or the _Atomic
compatibility macro, all of which use function-call-like syntax but
are definitely not function calls. So I would agree that it's not "a
normal C++ thing", but neither are various other parts of the
language.
> I know it's inherited from C, which doesn't have templates. But it's
> very bizarre in a C++ context, especially since C++ *already has*
> something that works like that. It creates a language wart, all in the
> name of backwards compatibility. Also, I'm not saying that this would
> be a problem for parsers; it's just a visual ugliness that's very
> foreign to C++ mechanisms.
If you find it visually ugly, don't use it.
The issue is that it will inevitably exist. We have created the
_Atomic compatibility macro, which allows you to create
C-interoperable headers where the same spelling is used "on both
sides". The point of _BitInt in C++ (as a macro or keyword) is the
exact same, and that keyword already exists in Clang. Defining the
keyword in C++ simply cuts out the unnecessary middle-man of a
compatibility macro, and that's beneficial to those who write such
interoperable headers.
> does `N` work? `bit_int<N>` works in a way that we understand in C++
> because... it's a template. It looks like a type generated via a
> template. `_BitInt(N)` looks like a function call. For `bit_int<N>`,
> `N` is a template argument. Therefore it must be a constant
> expression.
Well, how does N work in int[N]? The answer is that you don't really
have to know if you just use std::array<int, N> and don't get in touch
with these mechanisms inherited from C. So to answer your question,
don't ask, just use std::bit_int<N>. The alias template should
definitely be the one taught to new C++ developers.
> But for `_BitInt(N)`... what is `N` allowed to be? C++ does have
> `consteval` functions that forbid taking non-constant expression
> parameters, but `_BitInt` is *not* a function call. It's a thing that
> looks like a function call that results in a type? While C++ may
> eventually have something like that post-reflection, it's not a normal
> C++ thing right now.
I don't think _BitInt is any less usual than static_assert or
delete("reason") or sizeof or typeof or alignas or the _Atomic
compatibility macro, all of which use function-call-like syntax but
are definitely not function calls. So I would agree that it's not "a
normal C++ thing", but neither are various other parts of the
language.
> I know it's inherited from C, which doesn't have templates. But it's
> very bizarre in a C++ context, especially since C++ *already has*
> something that works like that. It creates a language wart, all in the
> name of backwards compatibility. Also, I'm not saying that this would
> be a problem for parsers; it's just a visual ugliness that's very
> foreign to C++ mechanisms.
If you find it visually ugly, don't use it.
The issue is that it will inevitably exist. We have created the
_Atomic compatibility macro, which allows you to create
C-interoperable headers where the same spelling is used "on both
sides". The point of _BitInt in C++ (as a macro or keyword) is the
exact same, and that keyword already exists in Clang. Defining the
keyword in C++ simply cuts out the unnecessary middle-man of a
compatibility macro, and that's beneficial to those who write such
interoperable headers.
Received on 2025-09-01 19:14:40