Conditional Operator Differences Between C and C++

Conditional operator differences between C and C++

The conditional operator in C++ can return an lvalue, whereas C does not allow for similar functionality. Hence, the following is legal in C++:

(true ? a : b) = 1;

To replicate this in C, you would have to resort to if/else, or deal with references directly:

*(true ? &a : &b) = 1;

Also in C++, ?: and = operators have equal precedence and group right-to-left, such that:

(true ? a = 1 : b = 2);

is valid C++ code, but will throw an error in C without parentheses around the last expression:

(true ? a = 1 : (b = 2));

Ternary operator in C vs C++

Have a look at the operator precedence.

Without an explicit () your code behaves like

( a >= 5 ? b = 100 :  b ) = 200;

The result of a ?: expression is not a modifiable lvalue [#] and hence we cannot assign any values to it.

Also, worthy to mention, as per the c syntax rule,

assignment is never allowed to appear on the right hand side of a conditional operator

Relared Reference : C precedence table.

OTOH, In case of c++, well,

the conditional operator has the same precedence as assignment.

and are grouped right-to-left, essentially making your code behave like

 a >= 5 ? (b = 100) : ( b = 200 );

So, your code works fine in case of c++


[ # ] -- As per chapter 6.5.15, footnote (12), C99 standard,

A conditional expression does not yield an lvalue.

C++ Conditional Operator versus if-else

The key difference between the conditional operator and an if/else block is that the conditional operator is an expression, rather than a statement. Thus, there are few places you can use the conditional operator where you can't use an if/else. For example, initialization of constant objects, like so:

const double biasFactor = (x < 5) ? 2.5 : 6.432;

If you used if/else in this case, biasFactor would have to be non-const.

Additonally, constructor initializer lists call for expressions rather than statements as well:

X::X()
: myData(x > 5 ? 0xCAFEBABE : OxDEADBEEF)
{
}

In this case, myData may not have any assignment operator or non-const member functions defined--its constructor may be the only way to pass any parameters to it.

Also, note that any expression can be turned into a statement by adding a semicolon at the end--the reverse is not true.

Ternary operator in java vs c

Because you can't assign a statement like that in Java. Your ternary would work if you used it like,

System.out.println(i%2==0 ? "even" : "odd");

Fundamentally, Java isn't C.

Edit

You ask in the comments, where am i assigning anything?

To quote Equality, Relational, and Conditional Operators (The Java Tutorials),

Another conditional operator is ?:, which can be thought of as shorthand for an if-then-else statement (discussed in the Control Flow Statements section of this lesson). This operator is also known as the ternary operator because it uses three operands. In the following example, this operator should be read as: "If someCondition is true, assign the value of value1 to result. Otherwise, assign the value of value2 to result."

Further, Chapter 15. Expressions - Conditional Operator ? : (JLS-15.25) says

It is a compile-time error for either the second or the third operand expression to be an invocation of a void method.

What is the difference between logical and conditional AND, OR in C#?

I prefer to think of it as "bitwise vs. conditional" rather than "logical vs conditional" since the general concept of "logical" applies in both cases.

x & y    // bitwise AND, 0101 & 0011 = 0001
x | y // bitwise OR, 0101 | 0011 = 0111

x && y // true if both x and y are true
x || y // true if either x or y are true

Edit

By popular demand, I should also mention that the arguments are evaluated differently. In the conditional version, if the result of the entire operation can be determined by the first argument, the second argument is not evaluated. This is called short-circuit evaluation. Bitwise operations have to evaluate both sides in order to compute the final value.

For example:

x.foo() && y.bar()

This will only call y.bar() if x.foo() evaluates to true. Conversely,

x.foo() || y.bar()

will only call y.bar() if x.foo() evaluates to false.

What is the type of an expression with a conditional operator in C?

The standard C17 6.5.15 specifies that the operands must behave according to this:

Constraints

The first operand shall have scalar type.

One of the following shall hold for the second and third operands:

— both operands have arithmetic type;

— both operands have the same structure or union type;

— both operands have void type;

— both operands are pointers to qualified or unqualified versions of compatible types;

— one operand is a pointer and the other is a null pointer constant; or

— one operand is a pointer to an object type and the other is a pointer to a qualified or

unqualified version of void.


In your example, (x>y) ? printf("type of int") : func_string();, printf returns type int which is an arithmetic type. func_string() supposedly returns a char*, which is a pointer type. This use case doesn't match any of the above listed valid scenarios, since the types are not compatible.

And so the compiler reports that the code isn't valid C. Some examples of compiler diagnostics:

icc:

operand types are incompatible ("int" and "char *")

gcc:

pointer/integer type mismatch in conditional expression


In case the 2nd and 3rd operands had been compatible or at least both arithmetic types (one float and one int etc), then this rule from 6.5.15 applies:

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.

To understand that part, you need to understand the meaning of the usual arithmetic conversions, see Implicit type promotion rules

The bottom line is that ?: is not some glorified if-else replacement, but a rather peculiar operator that comes with lots of special rules. ?: also has very few valid use-cases in real C code, one of the few valid uses for it is certain function-like macros.

Can I use bitwise operators instead of conditional operators in C?

As pointed out in comments:

1 && 2 is true, 1 & 2 is false.

Also,

Bitwise operators don't short-circuit.

Difference Between C and Python Ternary Operators

Now my questions are...

How Python is more Pythonic here? "Simple is better than complex" failed here in my opinion. If I am wrong please clarify me. I want to
know what I am missing?

The English sentence is

we go to the beach if the weather is nice, else we stay at home.

Highlight the right words, leave out the fillers:

gotobeach if weather == "nice" else stayathome

that looks a lot like valid Python ;)

Execution order of C and Python conditional expression is completely different I see.

No. It's not.

First, the line is parsed, then the condition after if is evaluated, then either one of the statements is evaluated.

Difference between C# and Java's ternary operator (? :)

Looking through the C# 5 Language Specification section 7.14: Conditional Operator we can see the following:

  • If x has type X and y has type Y then

    • If an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the
      conditional expression.

    • If an implicit conversion (§6.1) exists from Y to X, but not from X to Y, then X is the type of the
      conditional expression.

    • Otherwise, no expression type can be determined, and a compile-time error occurs

In other words: it tries to find whether or not x and y can be converted to eachother and if not, a compilation error occurs. In our case int and string have no explicit or implicit conversion so it won't compile.

Contrast this with the Java 7 Language Specification section 15.25: Conditional Operator:

  • If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression. (NO)
  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T. (NO)
  • If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type. (NO)
  • Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases: (NO)
  • Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2.

    The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1, T2) (§15.12.2.7). (YES)

And, looking at section 15.12.2.7. Inferring Type Arguments Based on Actual Arguments we can see it tries to find a common ancestor that will serve as the type used for the call which lands it with Object. Object is an acceptable argument so the call will work.

Difference between ternary (conditional) operator and if statement returning an Action

Why explicit cast is required in Conditional operator

_doSomething = ThisOrThat ?  DoThis : DoThat; 

From this answer from Jon Skeet:

as the expression. What's the type of that? What delegate type should
the method groups be converted to? The compiler has no way of
knowing
. If you cast one of the operands, the compiler can check
that the other can be converted though

For your question:

Why it is allowed in if statement

You are doing a simple assignment where left hand side is Action and the right hand side is a method group. There exists implicit conversion

See Assignment Operator(=) C#

The assignment operator (=) stores the value of its right-hand operand
in the storage location, property, or indexer denoted by its left-hand
operand and returns the value as its result. The operands must be of
the same type (or the right-hand operand must be implicitly
convertible to the type of the left-hand operand
)



Related Topics



Leave a reply



Submit