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:
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:
a
to booleana
expr
, convert result to boolean, assign to a
, and return itThe steps above seem to be the same for both the assignment and normal case.
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();