Date: Wed, 10 Sep 2025 09:23:44 +0200
On 10.09.25 05:51, Jason McKesson via Std-Proposals wrote:
> On Tue, Sep 9, 2025 at 11:03 PM Halalaluyafail3 via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>>
>> I understand that it's unlikely that such conversions will be removed. However,
>> I still think it's a bad idea to try and do this. _BitInt isn't meant to be a
>> replacement for the existing integer types, which it seems like you're
>> suggesting by saying programmers can opt into using these new types. They're
>> meant to complement the existing set of integer types. Trying to fix some of the
>> unfortunate design decisions every time a new feature gets added is not that
>> helpful and causes more problems than it is worth IMO. If for example a new type
>> long long long were to be added should we also try and disable some conversions
>> specifically for it? Maybe we could also add extra rules to the declaration
>> specifiers to prevent wacky stuff like long unsigned long int long.
>>
>> My point being: instead of trying to design new types to be perfect, just
>> understand that the language isn't perfect and probably won't be. If every new
>> feature is an opportunity to fix some minor issue then adding anything new will
>> be an uphill battle to convince everyone that it's perfect. Also, every fix is a
>> new inconsistency in the language. For example, imagine if every new container
>> had to use the name is_empty instead of empty to check if the container is
>> empty. is_empty is certainly a better name than empty, but it would make generic
>> code using is_empty/empty much more cumbersome.
>
> Well, the first thing is this: what does `_BitInt` *already* do in C?
> We're not speculating on a hypothetical feature. This is largely a
> compatibility exercise: making C++ do what C23 can do, possibly with a
> C++ coating of paint on it.
>
> So if `_BitInt` supports some operation in C, then the equivalent in
> C++ should too. If it explicitly forbids it, then the C++ equivalent
> should too.
In general, I don't follow that line of reasoning. There are plenty
of features in C that are not allowed in C++, e.g.
int * p = malloc(10); // cannot convert void* to int*
bool b = nullptr;
In none of these cases would I support loosening the rules in C++
to allow such implicit conversions.
_BitInt(N) is a new type, different from anything else we have in C++.
I can see that we want ABI compatibility with C for such a type
(cf. _Complex and (the failure of) _Atomic). So, we need to
recognize _BitInt(N) in C-style function declarations. We
also need a way to construct an object compatible with _BitInt(N)
in C++.
Do we need _BitInt as an enum underlying type or as a bit-field type?
I'm not convinced, even though those might appear in the API surface
of a C function. Instead of adding a special rule for _BitInt,
can we extend the core language to support arbitrary library types
in those places?
This covers the API/ABI surface; what follows are situations that
might appear in inline function definitions shared between C and C++:
Regarding "switch"; for a C++ ecosystem, we're on the way of
standardizing pattern matching as a generalized "switch".
For a C ecosystem, maybe there's appetite for supporting arbitrary
library types there.
Note that implicit conversions haven't shown up in this list yet.
I think C++ has a good freedom of design choice here. For inline
function definitions shared between C and C++, the programmer has
the option to convert explicitly instead of implicitly, which works
for both C and C++. In general, we're already past the point where
a C-only programmer can expect their arbitrary inline function to
"just work" with C++, without consideration of the limits of C++
compared to C (e.g. no VLAs), so asking the C programmer to choose
certain syntactic expressions over others for the sake of C++
compatibility is nothing new.
> No, the language will never be perfect. But that's not a good
> justification to keep making the same mistakes due to consistency.
Exactly.
> `_BitInt` is not meant to replace integer types;
We've learned time and again that "meant for" is soon lost in the
mists of time.
(Templates were never "meant for" template metaprogramming,
except that's where they shine most these days.)
Having a replacement for integers that people can opt into to avoid
overflow UB and various surprises around implicit conversions
seems like a nice step towards a safer language, too.
Jens
> On Tue, Sep 9, 2025 at 11:03 PM Halalaluyafail3 via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>>
>> I understand that it's unlikely that such conversions will be removed. However,
>> I still think it's a bad idea to try and do this. _BitInt isn't meant to be a
>> replacement for the existing integer types, which it seems like you're
>> suggesting by saying programmers can opt into using these new types. They're
>> meant to complement the existing set of integer types. Trying to fix some of the
>> unfortunate design decisions every time a new feature gets added is not that
>> helpful and causes more problems than it is worth IMO. If for example a new type
>> long long long were to be added should we also try and disable some conversions
>> specifically for it? Maybe we could also add extra rules to the declaration
>> specifiers to prevent wacky stuff like long unsigned long int long.
>>
>> My point being: instead of trying to design new types to be perfect, just
>> understand that the language isn't perfect and probably won't be. If every new
>> feature is an opportunity to fix some minor issue then adding anything new will
>> be an uphill battle to convince everyone that it's perfect. Also, every fix is a
>> new inconsistency in the language. For example, imagine if every new container
>> had to use the name is_empty instead of empty to check if the container is
>> empty. is_empty is certainly a better name than empty, but it would make generic
>> code using is_empty/empty much more cumbersome.
>
> Well, the first thing is this: what does `_BitInt` *already* do in C?
> We're not speculating on a hypothetical feature. This is largely a
> compatibility exercise: making C++ do what C23 can do, possibly with a
> C++ coating of paint on it.
>
> So if `_BitInt` supports some operation in C, then the equivalent in
> C++ should too. If it explicitly forbids it, then the C++ equivalent
> should too.
In general, I don't follow that line of reasoning. There are plenty
of features in C that are not allowed in C++, e.g.
int * p = malloc(10); // cannot convert void* to int*
bool b = nullptr;
In none of these cases would I support loosening the rules in C++
to allow such implicit conversions.
_BitInt(N) is a new type, different from anything else we have in C++.
I can see that we want ABI compatibility with C for such a type
(cf. _Complex and (the failure of) _Atomic). So, we need to
recognize _BitInt(N) in C-style function declarations. We
also need a way to construct an object compatible with _BitInt(N)
in C++.
Do we need _BitInt as an enum underlying type or as a bit-field type?
I'm not convinced, even though those might appear in the API surface
of a C function. Instead of adding a special rule for _BitInt,
can we extend the core language to support arbitrary library types
in those places?
This covers the API/ABI surface; what follows are situations that
might appear in inline function definitions shared between C and C++:
Regarding "switch"; for a C++ ecosystem, we're on the way of
standardizing pattern matching as a generalized "switch".
For a C ecosystem, maybe there's appetite for supporting arbitrary
library types there.
Note that implicit conversions haven't shown up in this list yet.
I think C++ has a good freedom of design choice here. For inline
function definitions shared between C and C++, the programmer has
the option to convert explicitly instead of implicitly, which works
for both C and C++. In general, we're already past the point where
a C-only programmer can expect their arbitrary inline function to
"just work" with C++, without consideration of the limits of C++
compared to C (e.g. no VLAs), so asking the C programmer to choose
certain syntactic expressions over others for the sake of C++
compatibility is nothing new.
> No, the language will never be perfect. But that's not a good
> justification to keep making the same mistakes due to consistency.
Exactly.
> `_BitInt` is not meant to replace integer types;
We've learned time and again that "meant for" is soon lost in the
mists of time.
(Templates were never "meant for" template metaprogramming,
except that's where they shine most these days.)
Having a replacement for integers that people can opt into to avoid
overflow UB and various surprises around implicit conversions
seems like a nice step towards a safer language, too.
Jens
Received on 2025-09-10 07:23:48