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 <
I guess the simple answer is that ||
is a boolean operator: and in C, a "boolean" is 0 or 1. The operands are implicitly converted to booleans (I have not checked that that's what the spec actually says, but it's how C behaves), and the result is a boolean.
Altering the semantics to support this pattern may well be feasible -- until someone relies on ||
doing what it's always done.
Because the return type of operators ||
and &&
is not the same as type of their left argument.
The return type of ||
and &&
is always int
1, 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
.
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();
I cannot find any particular reason, why the operators don't exist (in C99).
So the only reason I can find is, that there was no boolean type in C89, and those boolean operators were intended to be solely used in if
's.
Example:
int i = 5;
/* This should not make any difference,
since or'ing with false, shouldn't change
the value... dib di dib diddy...*/
i ||= 0; /* Actually: i = i || 0, which gives 'true' */
i
is now '1'', which for most people is pretty counter intuitive.
This operator obviously doesn't bring any clearence or coding improvement without the boolean type, that would make sence being or'd with another one.
In my opinion, the implementation of a ||= b;
as if(!a) a = b;
would be pretty straightforward and has aleardy been implemented by e.g. Lua.
So you're question seems to be a bit, why C has been designed the way it has been designed. If this question was about C++, you could for example ask Bjarne Stroustrup and ask him, what had went into him. Since this is not the case, this seems to me to be kind of a dead end, because the standard has been written quite some time ago and you cannot really ask people anymore, why the h***.
On the other hand, this incomplete operator set should (in my opinion) aleardy have been made whole using a similar notation than yours, since in my opinion, there is no reason against it.
I hope I could help a little.