Andrey Tarasevich <
andreyta...@hotmail.com> writes:
> On 8/16/2022 12:12 AM, David Brown wrote:
>
>>> Secondly, in any case these rules cannot be brushed off under "not
>>> triggered" premise because the very last rule in the list is a
>>> "sink": it is not protected by a trigger at all, it is
>>> unconditional. If none of the previous rules are "triggered" then
>>> the last rule applies:
>>>
>>>
http://eel.is/c++draft/expr.arith.conv#1.3.5
>>> - Otherwise, both operands are converted to the unsigned integer
>>> type corresponding to the type of the operand with signed integer
>>> type.
>>>
>>> What do you expect this to do if one operand is a pointer?
>>
>> It doesn't get that far. As I interpret this, only the bool gets
>> the "usual arithmetic conversions" - thus references to "both
>> operands" only apply to the single operand. After the integral
>> promotions are performed (turning the bool into int), we get "If
>> both operands have the same type, no further conversion is needed"
>> and stop there.
>
> But... why? Why do we suddenly stop at "If both operands have the
> same type..."? We have a pointer and a bool. How is that "the
> same type", even if you promote the bool to an integer?
It occurs to me that the problem here is not with the description
of additive operators (section 7.6.6) but with section 7.4, which
defines the usual arithmetic conversions. What we have in the
case of a pointer and a bool is not two operands but one operand,
that is, just the bool (remember that 7.6.6 p1 says "The usual
arithmetic conversions are performed for operands of arithmetic
or enumeration type", which is just the bool operand in this
case). Section 7.4 is written with the assumption that there
will be two operands being treated, but in this case there is
only one. Thus a solution is to revise 7.4 so it addresses the
more general scenario of converting one or more operands. Here
is a draft of a possible revision:
Many operators that expect one or more operands of arithmetic
or enumeration type cause conversions and yield result types in
a similar way. The purpose is to yield a common type, which is
also the type of the result. This pattern is called the usual
arithmetic conversions, which are defined as follows:
(1.1) -- If any operand is of scoped enumeration type no
conversions are performed; if any other operand does not have
the same type, the expression is ill-formed.
(1.2) -- If any operand is of type long double, all other
operands shall be converted to long double.
(1.3) -- Otherwise, if any operand is double, all other
operands shall be converted to double.
(1.4) -- Otherwise, if any operand is float, all other
operands shall be converted to float.
(1.5) -- Otherwise, the integral promotions shall be
performed on all operands. Then the following rules shall
be applied to the promoted operands:
(1.5.1) -- If all operands have the same type, no further
conversion is needed.
(1.5.2) -- Otherwise, if all operands have signed integer types
or all operands have unsigned integer types, all operands with
a type of lesser integer conversion rank shall be converted to
an operand type having the greatest integer conversion rank.
(1.5.3) -- Otherwise, if an operand that has unsigned integer
type has an integer conversion rank that is greater than or
equal to the rank of the type of all other operands, all other
operands shall be converted to the type of the unsigned integer
operand with the greatest integer conversion rank.
(1.5.4) -- Otherwise, if the type of the operand with signed
integer type can represent all of the values of the type of all
other operands, those operands shall be converted to the type
of the signed integer operand with the greatest integer
conversion rank.
(1.5.5) -- Otherwise, all operands shall be converted to the
unsigned integer type corresponding to the type of an operand
with signed integer type having the greatest integer conversion
rank.
2 If one operand is of enumeration type and any other operand
is of a different enumeration type or a floating-point type,
this behavior is deprecated.
Taking this approach solves the problem for section 7.6.6 and
also anticipates possible future additions to the language that
have more than two operands.