Why does C not have a logical assignment operator?

Manav picture Manav · Aug 17, 2010 · Viewed 12.7k times · Source

I had the need to code a statement of the form

a = a || expr;

where expr should be evaluated and the result be assigned to a iff a is not set. this relies on the logical OR's short-circuiting capabilities.

The shorter way to write the above would, of course, be

a ||= expr;

but (to my surprise) C does not have logical assignment operators.

So my question is twofold. First, is there a shorter way to write the first statement in standard C (the ternary operator is even worse - a = a ? a : expr requires me to spell out a thrice).

Secondly, why aren't there logical assignments in C? The possible reasons I could think of are:

  • it makes the grammar harder to parse?
  • there is some subtlety in handling short-circuiting for these cases?
  • it was considered superfluous (but isn't that an argument against ALL the operator assignments?)

EDIT

Please unlock this question because:

  • The question it has been linked to (as a alleged duplicate of) HAS NOT BEEN ANSWERED. The (accepted) answer to that question states that ||= is not present because duplicates the functionality of |=. That is the wrong answer. |= does not short-circuit.

  • C and C++ are NOT the same languages. I wish to know why C doesn't have it. In fact, the fact that derived languages like C++ and, particularly, Java (which did not suffer from the problems of legacy code as has been suggested in Edmund's answer) makes the question even more interesting.

EDIT 2

It now seems like my original intent was wrong. In the statement a = a || expr (where a is integral and expr returns an integral value, first both a and expr will be implicitly converted to "booleans", and then the "boolean" value will be assigned to a. This will be incorrect — the integral value will be lost. Thanks, Jens and Edmund.

So for the first part of the question, the correct ways, not alternatives :), to code my intention would be:

if (!a) a = expr;

or

a = a ? a : expr;

they should be optimized the same (I think) though personally I would prefer the first one (because it has one less a to type).

However, the second part of the question still remains. The arguments that Jens and Edmund about have given about the ambiguity in a ||= expr apply equally well to a = a || expr. the assignment case can simply be treated as the normal one:

  • convert a to boolean
  • if it is true, the value of the entire expression becomes equal to the boolean value of a
  • otherwise evaluate expr, convert result to boolean, assign to a, and return it

The steps above seem to be the same for both the assignment and normal case.

Answer

chux - Reinstate Monica picture chux - Reinstate Monica · Jul 14, 2015

a ||= expr is problematic due to short circuit evaluation of its equivalent a = a || expr.

To have a ||= expr function like a = a || expr consider OP's assertion:

"In the statement a = a || expr ..., first both a and expr will be implicitly converted to "booleans","

This is not quite correct. expr will not be converted if a evaluates to true. This would make a difference should expr be something like scanf() or rand() or some function that affected the state of the program.

Code such as a ||= scanf("%d", &i) != 1; would only attempt to scan data with a false value in a. Although it would be possible to extend the language this way, additional short-circuit operators to the current set of || and && would likely cause more coding problems than clear simplifications.

On the other hand: A quick, if obfuscated, way to write code where functions return non-zero codes on error.

// Perform functions until an error occurs.
bool error = foo1();
error &&= foo2();  // Only valid if C was extended with &&=
error &&= foo3();