Unexpected Type Resulting from the Ternary Operator

Unexpected type resulting from the ternary operator

As the other answers have stated, this behavior is because both possible results of a ternary expression must have the same type.

Therefore, all you have to do to make your ternary version work the same way as convert1() is to cast the int to an Object:

static Object convert2(double d) {
return ((d % 1) == 0) ? ((Object) (int) (d)) : d;
}

Ternary operator returns an unexpected output

please read the rules of ternary operator here

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25

1st one is result of If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression of type int whose value is representable in type T, then the type of the conditional expression is T. T being type char in this case and constant expression being 0

so the output is of type char which is x


2nd one is case for Otherwise, binary numeric promotion is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

read about binary numeric promotion here https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2

last case of point 2 applies here Otherwise, both operands are converted to type int. and converting char to int gives its ascii value which is 88

and hence the output is 88

Java - Assigning variable in ternary operator - unexpected type error

In Java the ternary operator is an "assignemnt" one, this means that the result of the operation "always" must be assigned to a variable.

The destination variable goes at left (as usual) of the symbol "=", whilst the operator goes at right.
As you said, it just works as an if/else. The structure is this one:

<destination_variable> = <condition> ? <value_if_cond_true> : <value_else>

So, in your specific case, the ternary operator will be written as follow:

int front = nums.length > 4 ? 4 : nums.length;

Why does the ternary operator unexpectedly cast integers?

You need to read section 15.25 of the Java Language Specification.

In particular:

Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:

  • If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short.
  • If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression of type int whose value is representable in type T, then > - the type of the conditional expression is T.
  • If one of the operands is of type Byte and the other operand is a constant expression of type int whose value is representable in type byte, then the type of the conditional expression is byte.
  • If one of the operands is of type Short and the other operand is a constant expression of type int whose value is representable in type short, then the type of the conditional expression is short.
  • If one of the operands is of type; Character and the other operand is a constant expression of type int whose value is representable in type char, then the type of the conditional expression is char.
  • Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13).

So binary numeric promotion is applied, which starts with:

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order, using widening conversion (§5.1.2) to convert operands as necessary:

  • If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed. Then:
  • If either operand is of type double, the other is converted to double.

That's exactly what happens here - the parameter types are converted to int and double respectively, the second operand (the third in the original expression) is then of type double, so the overall result type is double.

Ternary operator gives unexpected results in return statement

The ternary operator finds a common type and value category of both operands, and this doesn't happen for the two other cases, which is why it works there.

months_.Last() and Month() both have type Month, so everything is fine there. But now, let's examine the value categories. months_.Last() is an lvalue, while Month() is a prvalue! So, the common value category here is a prvalue, and both operands get converted to a prvalue. Which means that you get a new Month from months_.Last() every time (from the copy)!

Note again however, that this is a MS specific extension. Without that extension, the code would be invalid, as you would try to bind the prvalue returned by the conditional operator to a non-const lvalue reference.

Java Compile Error: Unexpected Type required: variable found: value

A ternary operator can only operate conditionally on values, not entire statements. Therefore, you would need to rewrite your code as:

this.bid = Double.isNaN(bid) ?  0.0 : bid;

Also, do you have a specific need to declare the field bid as a java.lang.Double (reference type) and not the primitive double?

Unexpected behaviour of ternary operator in C++

To understand the error, let's take a look the operands to the conditional operator.

The second operand:

mp[j]=1, vec.push_back(j)

The operand is two expressions separated by the comma operator.

The way the comma operator works here is that it evaluates mp[j]=1 which results in value 1, it discards the value and evaluates the next expression vec.push_back(j) which returns void.

Hence the final value of whole second operand is of type void (This is what the error says).

The third operand:

mp[j]=1

This expression evaluates to 1, which is of type int. (Thus it is not void or thrown-exception, and that is what the error says).

When you change the second operand:
In the expression

vec.push_back(j), mp[j]=1

vec.push_back(j) evaluates to void, this value is discarded and then mp[j]=1 evaluates to 1 which is type int. Now both operands are int, hence no error.

Ternary operator with different types of expressions

In Java, you have compile time type information and you have run time type information. Compile time type information is what the compiler can deduce about the type of a value or expression just by looking at it, but without executing it. When the compiler sees the expression

2 == 3 ? 0xF00 : "bar"

It does not know whether 2 == 3 will be true or false, because it does not execute code. So all it knows is that the result can be an Integer, or a String. So when the time comes to pick which foo method to call, it picks the one that accepts Object, since that is the only one that it knows will work in both scenarios.

However, when the code is actually running, 2 == 3 will be false, and the result will be a String, whose getClass() method will return String.class. And that is what you need to note: getClass() does not return the type that the variable had at compile time, but it returns the actual type of the object that the variable holds at run time. i.e.

Object o = "Hello!";
System.out.println(o.getClass());

will print java.lang.String, because even though to the compiler it is an Object, at run time it is actually a String.

Ternary Operator (?:) based assignment avoids type check in C

From the C Standard (6.5.15 Conditional operator)


  1. ... 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.

The function malloc returns a pointer of the type void *. So the type of the expression with the conditional operator is void *. And a pointer of the type void * can be assigned to a pointer of any other object type.

From the C Standard (6.3.2.3 Pointers)

1 A pointer to void may be converted to or from a pointer to any
object type. A pointer to any object type may be converted to a
pointer to void and back again; the result shall compare equal to the
original pointer.

In fact you have

a = ( void * )(b >= 8 ? array : malloc(8) );


Related Topics



Leave a reply



Submit