Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does C not have a logical assignment operator?

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.

like image 708
Manav Avatar asked Aug 17 '10 09:08

Manav


People also ask

Does C have assignment operators?

Assignment Operators in C/C++ Assignment operators are used to assigning value to a variable. The left side operand of the assignment operator is a variable and right side operand of the assignment operator is a value.

What is logical not operator in C?

The “not” (!) The “not” logical operator is used to convert a value from true to false, or from false to true. Similarly, if an operand evaluates to true, a logical “not” would cause it to evaluate to false. If an operand evaluates to false, its logical “not” equivalent would be true.

Is assignment operator a logical operator?

An assignment operator is the operator used to assign a new value to a variable, property, event or indexer element in C# programming language. Assignment operators can also be used for logical operations such as bitwise logical operations or operations on integral operands and Boolean operands.

What is logical or operator in C?

The logical-OR operator performs an inclusive-OR operation on its operands. The result is 0 if both operands have 0 values. If either operand has a nonzero value, the result is 1. If the first operand of a logical-OR operation has a nonzero value, the second operand isn't evaluated.


2 Answers

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(); 
like image 163
chux - Reinstate Monica Avatar answered Oct 15 '22 06:10

chux - Reinstate Monica


Because the return type of operators || and && is not the same as type of their left argument.

The return type of || and && is always int1, while the left argument may be any integral, floating point or pointer type. The operands also don't have to be of the same type. Therefore defining x ||= y as x = x || y and x &&= y as x = x && y as would be consistent with other augmented assignments would not be able to store the result in the argument for most types.

You could come up with other definitions, e.g. x ||= y as if(!x) x = y and x &&= y as if(!y) x = y, but that would not be exactly obvious and it is not that useful, so it was not included.

1In C++ it is bool.

like image 36
Jan Hudec Avatar answered Oct 15 '22 07:10

Jan Hudec