Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ternary operator with branches with void type

Is it safe to use ternary operator with functions which return void? Something like this:

void foo1(){}
void foo2(){}

//////////////

bool to_use_1 = ....;
to_use_1 ? foo1() : foo2();

Can compiler delete this code? Suppose it will treats such functions as pure, and perform agressive optimization which delete these calls

like image 549
LmTinyToon Avatar asked Apr 03 '17 17:04

LmTinyToon


People also ask

Is ternary operator branching?

In ESSL and GLSL the ternary operator will always lead to branching. It is not a vector operator, so the condition has to evaluate to a boolean.

Can ternary operator have three conditions?

The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark ( ? ), then an expression to execute if the condition is truthy followed by a colon ( : ), and finally the expression to execute if the condition is falsy.

Can ternary operator have multiple conditions?

We can nest ternary operators to test multiple conditions.

What are the three arguments of a ternary operator?

The ternary operator take three arguments: The first is a comparison argument. The second is the result upon a true comparison. The third is the result upon a false comparison.


1 Answers

First of all, the compiler will/should never logically "delete" any calls that have observable effects (with the sole exception of copy elision). That's simply not something it's allowed to do, no matter how aggressive the optimisation mode.

The C++ standard in fact makes explicit allowance for the result of your conditional operator's operands to be void, so this is expected and safe. However, it does have to be both.

[C++14: 5.16/1]: Conditional expressions group right-to-left. The first expression is contextually converted to bool (Clause 4). It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. Only one of the second and third expressions is evaluated. Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.

[C++14: 5.16/2]: If either the second or the third operand has type void, one of the following shall hold:

  • The second or the third operand (but not both) is a (possibly parenthesized) throw-expression (15.1); the result is of the type and value category of the other.

  • Both the second and the third operands have type void; the result is of type void and is a prvalue. [ Note: This includes the case where both operands are throw-expressions. —end note ]

Technically, this wording (in its talk about "values") doesn't outright spell out that exactly one of the second and third expressions is evaluated, even when those evaluations have no "value". But it's essentially indisputable from the standpoint of analysis. There may be a case for an editorial improvement here.

Note that none of this guarantees that your computer will actually jump, during execution, into foo1 or foo2; in the specific example you give, the compiler can immediately see that both functions are completely empty, and optimise away the entire line of code. But that does not affect the semantics of your program, nor is it specific to use of the conditional operator.

like image 170
Lightness Races in Orbit Avatar answered Oct 16 '22 10:10

Lightness Races in Orbit