Date: Wed, 3 Sep 2025 11:01:58 +0200
On 02/09/2025 21:12, Hans Åberg wrote:
>
>
>> On 2 Sep 2025, at 20:34, David Brown <david.brown_at_[hidden]> wrote:
>>
>> On 02/09/2025 18:58, Hans Åberg wrote:
>>>> On 2 Sep 2025, at 18:36, David Brown <david.brown_at_[hidden]> wrote:
>>>>
>>>> On 02/09/2025 17:59, Hans Åberg wrote:
>>>>>> On 2 Sep 2025, at 16:01, David Brown <david.brown_at_[hidden]> wrote:
>>>>>>
>>>>>> On 02/09/2025 15:24, Hans Åberg wrote:
>>>>>>>> On 2 Sep 2025, at 14:49, David Brown via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>>>>>>
>>>>>>>> On 02/09/2025 14:24, Hans Åberg via Std-Proposals wrote:
>>>>>>>>>> On 2 Sep 2025, at 14:14, Jan Schultke <janschultke_at_[hidden]> wrote:
>>>>>>>>>>
>>>>>>>>>> You seem to be confusing some mostly unrelated concepts.
>>>>>>>>>>
>>>>>>>>>>>> 1. C does not allow _BitInt(1); should C++ to make generic programming
>>>>>>>>>>>> more comfortable?
>>>>>>>>>>>
>>>>>>>>>>> The ring ℤ/2ℤ of integers modulo 2, also a field, is isomorphic to the Boolean ring 𝔹 having exclusive or as addition and logical conjunction as multiplication.
>>>>>>>>>>>
>>>>>>>>>>> If bool 1+1 is defined to 0, then it is already in C++.
>>>>>>>>>>
>>>>>>>>>> Whether there is some other C++ thing that works mathematically the
>>>>>>>>>> same doesn't say anything about whether _BitInt(1) is valid or should
>>>>>>>>>> be valid. The issue is regarding a specific type.
>>>>>>>>> It could have been defined to be the same as bool.
>>>>>>>>
>>>>>>>> No, it could not. _BitInt(1), if it is to exist, has the two values -1 and 0. Like all signed integer types, arithmetic overflow on it is undefined, and like all _BitInt types, there is no integer promotion. Thus for _BitInt(1), (-1) + (-1) is UB.
>>>>>>>>
>>>>>>>> unsigned _BitInt(1) can hold 0 and 1, has no integer promotion, and has modulo arithmetic behaviour - thus 1 + 1 gives 0 for "unsigned _BitInt(1)".
>>>>>>> Right. I was thinking about the unsigned type only.
>>>>>>
>>>>>> Certainly "unsigned _BitInt(1)" is more akin to how booleans often work in programming languages. It is a 2-element finite field. (bool in C++ is not a field - it has no addition or multiplication operations. "true + true" is the int value 2, while "true * true" is the int value 1.)
>>>>> One would have to make new type, as bool just expresses the behavior of the logical operators on int.
>>>>
>>>> What would you need a new type for? What could you do with it, that you cannot do with bool today, in C or C++ ?
>>> One reason is to avoid common mistakes, like confusing assignment and equality.
>>
>> That would be a justification for removing certain operations from today's bool.
>
> It would suffice with a Boolean type that does have implicit conversions with int.
Did you mean to write "does /not/ have implicit conversions with int" ?
The awkward thing here is that bool has virtually no operations in
itself - pretty much everything is done after implicitly converting it
to int. You can't even compare two bool's for equality without them
being subject to integer promotions - so if you simply dropped implicit
conversion to int, you'd now have to write "if (int(bool_a) ==
int(bool_b))".
I agree with your aim here, but it would unfortunately be difficult to
achieve with a change to existing C++.
>
>> I can't see any reason for adding bool values, or for multiplying two bool values (but multiplying a bool and another integer type is common).
>
> It just came up that it is the modular size 1 bit int.
"bool" in C++ is not a modular type.
>
>> I'm sure there are other operators that could be removed without too much risk to existing code - though I don't know if it is worth the effort. (After all, compilers could simply add warnings for questionable usage, without changing the standards.)
>
> If one des not have those implicit conversions, it probably does not matter much what operations one has.
>
I would not want to remove integer promotions from bool and then
implement arithmetic operators on it - that would be counter-productive.
If standard bool were to be improved (and it's a pretty hypothetical
"if"), you'd really have to allow implicit conversions in some contexts
but not others, or remove implicit conversions and add new operations on
bools.
>>>> Some changes /do/ make sense, such as the removal of the increment and decrement operators on bool in C++17. I think it might make sense to limit other arithmetic operators on bools, or at least when operating on two bools - the promotion of bool to int can be convenient in some expressions.
>>> The current bool is useful, as there may not be good support on the assembler level for other types.
>>
>> I don't follow. The current bool is useful - of that there is no doubt. That is the case regardless of what cpu instruction level support there might be for things that are a bit like bool, but which behave somewhat differently.
>
> Requiring bool to have modular arithmetic might burden it, so since there are no good use cases, not worth to pursue.
>
Supporting one-bit modular arithmetic is not going to be challenging on
any real-world hardware. Modular addition (and subtraction) is just
logical xor, and modular multiplication is just logical and.
But without extremely good use-cases, it would be hard to justify
changing bool to be a modular 1-bit type, or adding a modular 1-bit type
to the language - especially as you can get the effect with "xor" and
"and" in the language already.
However, it's fine that unsigned _BitInt(1) is a modular 1-bit type
since that is part of _BitInt. You just wouldn't bother adding it by
itself.
>> You still have not said how you think another kind of bool-like type could work, what differences it would have from today's bool (in C++ or C), and why you think those differences would be a good idea.
>
> Only a type that does not have the implicit conversions to the int. If conditionals, one would have to use a Boolean operator or an explicit conversion.
>
>>>>>>>> Both signed _BitInt(1) and unsigned _BitInt(1) are integer types representing numbers. In C23 (and presumably C++ when it gets _BitInt), these are included in the "standard integer types". "bool", on the other hand, is /not/ a standard integer type in C++ (though it is one in C).
>>>>>>> I get bool true + true = 2 also in C, so it seems it does not have proper arithmetic + in the sense that the results are the same as in conversion back and forth to int.
>>>>>>
>>>>>> That makes no sense. In C, "true" is the integer constant 1 - of type "int". "_Bool" is an unsigned integer type with a range from 0 to 1 inclusive, and with the conversion operation that converting "x" to type "_Bool" is equivalent to assigning the result of "x != 0" (this comparison expression in C is of type "int", not "bool" like in C++).
>>>>>>
>>>>>> In C and C++, if you write an arithmetic expression with values or expressions of type "bool" (or "_Bool" in C, prior to C23), the subexpressions are promoted to "int" before applying the arithmetic operator.
>>>>>>
>>>>>> If you then assign (or convert) the results back to type "bool", it is handled as any other "int" to "bool" conversion - anything that compares not equal to 0 results in the bool value "true" in C++, or the int value 1 in C, while anything that compares equal to 0 is "false" or "0" respectively.
>>>>> So it makes the declaration that _Bool is an unsigned integer type useless, as the arithmetic cannot be accessed.
>>>>
>>>> Arithmetic on _Bool works fine - just like arithmetic on uint8_t works fine, along with any other unsigned integer type smaller than "int". There is the quirk that these promote to signed int, rather than unsigned int, but otherwise you can do unsigned arithmetic on them. The unusual thing about _Bool is how conversion from other types works when you assign to them - then they do not act like the other unsigned integer types. (But unsigned _BitInt(1) conversion is wrapping, like other unsigned integer types.)
>>> On a 1-bit modular arithmetic type, one should have 1+1=0. But I could not do that with the boolean types.
>>
>> I agree - on a 1-bit modular type, 1 + 1 should give 0. That is the case for unsigned _BitInt(1) in C23, as that is a 1-bit modular type.
>
> Good. The one might add logical operators to make it isomorphic to a Boolean type. :-)
The _BitInt types will already have logical operators, as they are
integer types. And they will be isomorphic to a kind of boolean type -
just not the same kind as C++'s "bool" type.
>
>> bool in C and C++ is /not/ a 1-bit modular type. It is a boolean type. Adding booleans does not make sense, and in languages with stricter typing, it will typically not be allowed by the language. C and C++ do not allow adding bools either - but they have an implicit conversion through integer promotion to convert bools to int, and then those are added. I can see an advantage in not allowing bools to be added, but I can see no point at all in defining it to give 0 (or did you mean "false" ?). After all, if you want an xor operation, use the xor operator.
>
> Yes, it does make sense, as it is isomorphic with ℤ/2ℤ. The confusion is with the implicit conversion with int, not what operations one has on the Boolean type.
>
>>>>>>>> Being able to represent two distinct values does not mean a type behaves like "bool".
>>>>>>>>
>>>>>>>>>>> However, in GCC and Clang, bool 1+1 = 1, and I could not see what the standard specifies.
>>>>>>>>>>
>>>>>>>>>> Any nonzero integer is true when converted to bool, so "bool(true +
>>>>>>>>>> true)" is essentially "1 + 1 != 0". bool gets promoted to int before
>>>>>>>>>> any operation.
>>>>>>>>> Apparently, there is no operator+ for bool. I did:
>>>>>>>>> bool a = 1, b = 1, c = a + b;
>>>>>>>>
>>>>>>>> Correct. There is also no "+" operator for char, or short int - other than _BitInt, types smaller than "int" get promoted to "int" before the operation.
>>>>>>> Right.
>>>>>>> The implicit down-conversions, that lose information, get in the way here.
>>>>>>
>>>>>> Integer promotions are value-preserving up-conversions, and do not lose information. (Some other implicit conversions can change values, but not the integer promotions.)
>>>>> It is the down-conversion from int to bool that loses information. Specifically, the conversion from any non-zero value to > 1. It is useful in C, which has a more primitive type system, and hard to change in C++ as it inherits that from C. If the > conversion from int to bool just throws away the higher bits, then the arithmetic comes out right, but would result in unexpected Boolean behavior.
>>>>
>>>> Conversion to a smaller type always loses information - "throw away the higher bits" loses information!
>>>>
>>>> The way conversion to bool works loses /different/ information than you would lose with a modulo reduction to a "normal" 1-bit unsigned integer (such as _BitInt(1) ). But the bool conversion is /vastly/ more useful than such a modulo reduction would be - it tells you if the original value was 0 or not, rather than if it was odd or even.
>>> The problem is really that these conversions are implicit, and one cannot turn off that to make them explicit only where required. One might achieve that with a proper boolean type, but not with all legacy code from C and C++.
>>
>> Ah, on that point I agree. Implicit conversion of bool to int, and from int to bool (and other narrowing conversions) are questionable features.
>
> I guess that is the whole issue, in fact.
>
>> It is not uncommon for people to define their own "strong_bool" classes that are like bool, but without the implicit conversions. Generally there is an explicit conversion operator to normal bool, so that you can use your strong_bool class easily in "if" statements and other conditionals.
>>
>>> So it would lead to a new language design, that might be difficult to make a part of C++.
>>
>> No, it is quite easy to implement today in C++ :
>>
>> class strong_bool {
>> private :
>> bool b_;
>> public :
>> strong_bool(bool b) : b_(b) {}
>> explicit operator bool() const { return b_; }
>> explicit operator int() const { return b_; }
>> friend strong_bool operator & (strong_bool x, strong_bool y) { return x.b_ & y.b_; }
>> friend strong_bool operator | (strong_bool x, strong_bool y) { return x.b_ | y.b_; }
>> friend strong_bool operator ^ (strong_bool x, strong_bool y) { return x.b_ ^ y.b_; }
>> friend strong_bool operator ! (strong_bool x) { return !x.b_; }
>> friend strong_bool operator == (strong_bool x, strong_bool y) { return x.b_ == y.b_; }
>> friend strong_bool operator != (strong_bool x, strong_bool y) { return x.b_ != y.b_; }
>> friend strong_bool operator < (strong_bool x, strong_bool y) { return x.b_ < y.b_; }
>> friend strong_bool operator <= (strong_bool x, strong_bool y) { return x.b_ <= y.b_; }
>> friend strong_bool operator > (strong_bool x, strong_bool y) { return x.b_ > y.b_; }
>> friend strong_bool operator >= (strong_bool x, strong_bool y) { return x.b_ >= y.b_; }
>> };
>>
>> What /would/ be difficult is changing all of the existing usage of "bool" in the C++ standard, library and code to use "strong_bool".
>
> I use a type which is a Boolean with an added value “undefined”, which I call “kleenean”. It is used for predicates with variables that have not yet been replaced with constants.
> https://cgit.git.savannah.gnu.org/cgit/metalogic-inference.git/tree/src/kleenean.hh
>
There are all kinds of extensions beyond true/false boolean types that
can be useful in different circumstances.
> Then I have problems with the implicit conversions. The undefined value is converted to int -1, but there is always the risk it gets further converted to a bool, and then it becomes true.
>
When it is your own type, /you/ control which conversions are implicit,
explicit, or not allowed at all.
>
>
>> On 2 Sep 2025, at 20:34, David Brown <david.brown_at_[hidden]> wrote:
>>
>> On 02/09/2025 18:58, Hans Åberg wrote:
>>>> On 2 Sep 2025, at 18:36, David Brown <david.brown_at_[hidden]> wrote:
>>>>
>>>> On 02/09/2025 17:59, Hans Åberg wrote:
>>>>>> On 2 Sep 2025, at 16:01, David Brown <david.brown_at_[hidden]> wrote:
>>>>>>
>>>>>> On 02/09/2025 15:24, Hans Åberg wrote:
>>>>>>>> On 2 Sep 2025, at 14:49, David Brown via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>>>>>>
>>>>>>>> On 02/09/2025 14:24, Hans Åberg via Std-Proposals wrote:
>>>>>>>>>> On 2 Sep 2025, at 14:14, Jan Schultke <janschultke_at_[hidden]> wrote:
>>>>>>>>>>
>>>>>>>>>> You seem to be confusing some mostly unrelated concepts.
>>>>>>>>>>
>>>>>>>>>>>> 1. C does not allow _BitInt(1); should C++ to make generic programming
>>>>>>>>>>>> more comfortable?
>>>>>>>>>>>
>>>>>>>>>>> The ring ℤ/2ℤ of integers modulo 2, also a field, is isomorphic to the Boolean ring 𝔹 having exclusive or as addition and logical conjunction as multiplication.
>>>>>>>>>>>
>>>>>>>>>>> If bool 1+1 is defined to 0, then it is already in C++.
>>>>>>>>>>
>>>>>>>>>> Whether there is some other C++ thing that works mathematically the
>>>>>>>>>> same doesn't say anything about whether _BitInt(1) is valid or should
>>>>>>>>>> be valid. The issue is regarding a specific type.
>>>>>>>>> It could have been defined to be the same as bool.
>>>>>>>>
>>>>>>>> No, it could not. _BitInt(1), if it is to exist, has the two values -1 and 0. Like all signed integer types, arithmetic overflow on it is undefined, and like all _BitInt types, there is no integer promotion. Thus for _BitInt(1), (-1) + (-1) is UB.
>>>>>>>>
>>>>>>>> unsigned _BitInt(1) can hold 0 and 1, has no integer promotion, and has modulo arithmetic behaviour - thus 1 + 1 gives 0 for "unsigned _BitInt(1)".
>>>>>>> Right. I was thinking about the unsigned type only.
>>>>>>
>>>>>> Certainly "unsigned _BitInt(1)" is more akin to how booleans often work in programming languages. It is a 2-element finite field. (bool in C++ is not a field - it has no addition or multiplication operations. "true + true" is the int value 2, while "true * true" is the int value 1.)
>>>>> One would have to make new type, as bool just expresses the behavior of the logical operators on int.
>>>>
>>>> What would you need a new type for? What could you do with it, that you cannot do with bool today, in C or C++ ?
>>> One reason is to avoid common mistakes, like confusing assignment and equality.
>>
>> That would be a justification for removing certain operations from today's bool.
>
> It would suffice with a Boolean type that does have implicit conversions with int.
Did you mean to write "does /not/ have implicit conversions with int" ?
The awkward thing here is that bool has virtually no operations in
itself - pretty much everything is done after implicitly converting it
to int. You can't even compare two bool's for equality without them
being subject to integer promotions - so if you simply dropped implicit
conversion to int, you'd now have to write "if (int(bool_a) ==
int(bool_b))".
I agree with your aim here, but it would unfortunately be difficult to
achieve with a change to existing C++.
>
>> I can't see any reason for adding bool values, or for multiplying two bool values (but multiplying a bool and another integer type is common).
>
> It just came up that it is the modular size 1 bit int.
"bool" in C++ is not a modular type.
>
>> I'm sure there are other operators that could be removed without too much risk to existing code - though I don't know if it is worth the effort. (After all, compilers could simply add warnings for questionable usage, without changing the standards.)
>
> If one des not have those implicit conversions, it probably does not matter much what operations one has.
>
I would not want to remove integer promotions from bool and then
implement arithmetic operators on it - that would be counter-productive.
If standard bool were to be improved (and it's a pretty hypothetical
"if"), you'd really have to allow implicit conversions in some contexts
but not others, or remove implicit conversions and add new operations on
bools.
>>>> Some changes /do/ make sense, such as the removal of the increment and decrement operators on bool in C++17. I think it might make sense to limit other arithmetic operators on bools, or at least when operating on two bools - the promotion of bool to int can be convenient in some expressions.
>>> The current bool is useful, as there may not be good support on the assembler level for other types.
>>
>> I don't follow. The current bool is useful - of that there is no doubt. That is the case regardless of what cpu instruction level support there might be for things that are a bit like bool, but which behave somewhat differently.
>
> Requiring bool to have modular arithmetic might burden it, so since there are no good use cases, not worth to pursue.
>
Supporting one-bit modular arithmetic is not going to be challenging on
any real-world hardware. Modular addition (and subtraction) is just
logical xor, and modular multiplication is just logical and.
But without extremely good use-cases, it would be hard to justify
changing bool to be a modular 1-bit type, or adding a modular 1-bit type
to the language - especially as you can get the effect with "xor" and
"and" in the language already.
However, it's fine that unsigned _BitInt(1) is a modular 1-bit type
since that is part of _BitInt. You just wouldn't bother adding it by
itself.
>> You still have not said how you think another kind of bool-like type could work, what differences it would have from today's bool (in C++ or C), and why you think those differences would be a good idea.
>
> Only a type that does not have the implicit conversions to the int. If conditionals, one would have to use a Boolean operator or an explicit conversion.
>
>>>>>>>> Both signed _BitInt(1) and unsigned _BitInt(1) are integer types representing numbers. In C23 (and presumably C++ when it gets _BitInt), these are included in the "standard integer types". "bool", on the other hand, is /not/ a standard integer type in C++ (though it is one in C).
>>>>>>> I get bool true + true = 2 also in C, so it seems it does not have proper arithmetic + in the sense that the results are the same as in conversion back and forth to int.
>>>>>>
>>>>>> That makes no sense. In C, "true" is the integer constant 1 - of type "int". "_Bool" is an unsigned integer type with a range from 0 to 1 inclusive, and with the conversion operation that converting "x" to type "_Bool" is equivalent to assigning the result of "x != 0" (this comparison expression in C is of type "int", not "bool" like in C++).
>>>>>>
>>>>>> In C and C++, if you write an arithmetic expression with values or expressions of type "bool" (or "_Bool" in C, prior to C23), the subexpressions are promoted to "int" before applying the arithmetic operator.
>>>>>>
>>>>>> If you then assign (or convert) the results back to type "bool", it is handled as any other "int" to "bool" conversion - anything that compares not equal to 0 results in the bool value "true" in C++, or the int value 1 in C, while anything that compares equal to 0 is "false" or "0" respectively.
>>>>> So it makes the declaration that _Bool is an unsigned integer type useless, as the arithmetic cannot be accessed.
>>>>
>>>> Arithmetic on _Bool works fine - just like arithmetic on uint8_t works fine, along with any other unsigned integer type smaller than "int". There is the quirk that these promote to signed int, rather than unsigned int, but otherwise you can do unsigned arithmetic on them. The unusual thing about _Bool is how conversion from other types works when you assign to them - then they do not act like the other unsigned integer types. (But unsigned _BitInt(1) conversion is wrapping, like other unsigned integer types.)
>>> On a 1-bit modular arithmetic type, one should have 1+1=0. But I could not do that with the boolean types.
>>
>> I agree - on a 1-bit modular type, 1 + 1 should give 0. That is the case for unsigned _BitInt(1) in C23, as that is a 1-bit modular type.
>
> Good. The one might add logical operators to make it isomorphic to a Boolean type. :-)
The _BitInt types will already have logical operators, as they are
integer types. And they will be isomorphic to a kind of boolean type -
just not the same kind as C++'s "bool" type.
>
>> bool in C and C++ is /not/ a 1-bit modular type. It is a boolean type. Adding booleans does not make sense, and in languages with stricter typing, it will typically not be allowed by the language. C and C++ do not allow adding bools either - but they have an implicit conversion through integer promotion to convert bools to int, and then those are added. I can see an advantage in not allowing bools to be added, but I can see no point at all in defining it to give 0 (or did you mean "false" ?). After all, if you want an xor operation, use the xor operator.
>
> Yes, it does make sense, as it is isomorphic with ℤ/2ℤ. The confusion is with the implicit conversion with int, not what operations one has on the Boolean type.
>
>>>>>>>> Being able to represent two distinct values does not mean a type behaves like "bool".
>>>>>>>>
>>>>>>>>>>> However, in GCC and Clang, bool 1+1 = 1, and I could not see what the standard specifies.
>>>>>>>>>>
>>>>>>>>>> Any nonzero integer is true when converted to bool, so "bool(true +
>>>>>>>>>> true)" is essentially "1 + 1 != 0". bool gets promoted to int before
>>>>>>>>>> any operation.
>>>>>>>>> Apparently, there is no operator+ for bool. I did:
>>>>>>>>> bool a = 1, b = 1, c = a + b;
>>>>>>>>
>>>>>>>> Correct. There is also no "+" operator for char, or short int - other than _BitInt, types smaller than "int" get promoted to "int" before the operation.
>>>>>>> Right.
>>>>>>> The implicit down-conversions, that lose information, get in the way here.
>>>>>>
>>>>>> Integer promotions are value-preserving up-conversions, and do not lose information. (Some other implicit conversions can change values, but not the integer promotions.)
>>>>> It is the down-conversion from int to bool that loses information. Specifically, the conversion from any non-zero value to > 1. It is useful in C, which has a more primitive type system, and hard to change in C++ as it inherits that from C. If the > conversion from int to bool just throws away the higher bits, then the arithmetic comes out right, but would result in unexpected Boolean behavior.
>>>>
>>>> Conversion to a smaller type always loses information - "throw away the higher bits" loses information!
>>>>
>>>> The way conversion to bool works loses /different/ information than you would lose with a modulo reduction to a "normal" 1-bit unsigned integer (such as _BitInt(1) ). But the bool conversion is /vastly/ more useful than such a modulo reduction would be - it tells you if the original value was 0 or not, rather than if it was odd or even.
>>> The problem is really that these conversions are implicit, and one cannot turn off that to make them explicit only where required. One might achieve that with a proper boolean type, but not with all legacy code from C and C++.
>>
>> Ah, on that point I agree. Implicit conversion of bool to int, and from int to bool (and other narrowing conversions) are questionable features.
>
> I guess that is the whole issue, in fact.
>
>> It is not uncommon for people to define their own "strong_bool" classes that are like bool, but without the implicit conversions. Generally there is an explicit conversion operator to normal bool, so that you can use your strong_bool class easily in "if" statements and other conditionals.
>>
>>> So it would lead to a new language design, that might be difficult to make a part of C++.
>>
>> No, it is quite easy to implement today in C++ :
>>
>> class strong_bool {
>> private :
>> bool b_;
>> public :
>> strong_bool(bool b) : b_(b) {}
>> explicit operator bool() const { return b_; }
>> explicit operator int() const { return b_; }
>> friend strong_bool operator & (strong_bool x, strong_bool y) { return x.b_ & y.b_; }
>> friend strong_bool operator | (strong_bool x, strong_bool y) { return x.b_ | y.b_; }
>> friend strong_bool operator ^ (strong_bool x, strong_bool y) { return x.b_ ^ y.b_; }
>> friend strong_bool operator ! (strong_bool x) { return !x.b_; }
>> friend strong_bool operator == (strong_bool x, strong_bool y) { return x.b_ == y.b_; }
>> friend strong_bool operator != (strong_bool x, strong_bool y) { return x.b_ != y.b_; }
>> friend strong_bool operator < (strong_bool x, strong_bool y) { return x.b_ < y.b_; }
>> friend strong_bool operator <= (strong_bool x, strong_bool y) { return x.b_ <= y.b_; }
>> friend strong_bool operator > (strong_bool x, strong_bool y) { return x.b_ > y.b_; }
>> friend strong_bool operator >= (strong_bool x, strong_bool y) { return x.b_ >= y.b_; }
>> };
>>
>> What /would/ be difficult is changing all of the existing usage of "bool" in the C++ standard, library and code to use "strong_bool".
>
> I use a type which is a Boolean with an added value “undefined”, which I call “kleenean”. It is used for predicates with variables that have not yet been replaced with constants.
> https://cgit.git.savannah.gnu.org/cgit/metalogic-inference.git/tree/src/kleenean.hh
>
There are all kinds of extensions beyond true/false boolean types that
can be useful in different circumstances.
> Then I have problems with the implicit conversions. The undefined value is converted to int -1, but there is always the risk it gets further converted to a bool, and then it becomes true.
>
When it is your own type, /you/ control which conversions are implicit,
explicit, or not allowed at all.
Received on 2025-09-03 09:02:06