I think ((1 ? (int)1 : (unsigned int)2) > -1)
results in 1
(true), but actually it is 0
(false) in Visual Studio 2017.
I think the value of (1 ? (int)1 : (unsigned int)2)
should be (int)1
, because 1 ?
is true, and 1 > -1
would be true.
I don't know the reason why the final result of this expression is false.
When I try casting like ((int)(1 ? (int)1 : (unsigned int)2) > -1)
, it returns 1
(true).
signed int test = -1;
signed int si = 1;
unsigned int ui = 2;
printf("%d\n", ((1 ? si : ui) > test));
return 0;
I expect the output to be 1
, but the actual output is 0
.
The type of a ? b : c
is not dependent on a
. It is determined unconditionally by the types of b
and c
. The full rules are complicated, but, for arithmetic operands, the type is determined by the usual arithmetic conversions. In effect, the two operands are converted to a common type. For int
and unsigned int
, the resulting type is unsigned int
.
The conditional operator, ? :
is described in clause 6.5.15 of the C 2018 standard. Paragraph 4 says the result is “converted to the type described below.”
Paragraph 5 describes the result for arithmetic types, structures, and unions:
If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result. If both the operands have structure or union type, the result has that type. If both operands have void type, the result has void type.
Arithmetic types are integer and floating-point types, per 6.2.5 18. (These include both real and complex types.) The usual arithmetic conversions are described in 6.3.1.8 1, which are (in my summary, not quoted):
long double
, the result is long double
.double
, the result is double
.float
, the result is float
.int
or narrower (meaning fewer bits or the same number of bits but signed instead of unsigned), the result is int
. Otherwise, if both are unsigned int
or narrower, the result is unsigned int
. Otherwise, the result is the wider type.The structure, union, and void rules are clear: The two operands must have the same type, and that is the result.
Paragraph 6 describes the result for pointers:
If both the second and third operands are pointers or one is a null pointer constant and the other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers of the types referenced by both operands. Furthermore, if both operands are pointers to compatible types or to differently qualified versions of compatible types, the result type is a pointer to an appropriately qualified version of the composite type; if one operand is a null pointer constant, the result has the type of the other operand; otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.
In summary, that says:
const
, volatile
, restrict
, or _Atomic
), include those in the result type.You should not mix signed and unsigned values unless you perfectly know what is unfolding (and you want that behavior) [checkout here why]. Behind the scenes, as you have an unsigned
number in your expression, C is evaluated your greater-than operator to an unsigned integer >
. Therefore, your comparison will not evaluate true
as "unsigned -1
" is greater than your unsigned 1
.
The result of your ?:
operator has unsigned type, since it is the common type for int
and unsigned
(your 2nd and 3rd operands). The result has the "expected" value of 1
, but its type is unsigned
.
The rest has nothing to do with ?:
at all. It is well-described in numerous answers for this frequently asked question: Comparison operation on unsigned and signed integers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With