问题
Possible Duplicates:
Why doesn't Java have compound assignment versions of the conditional-and and conditional-or operators? (&&=, ||=)
Why does a “&&=” Operator not exist?
Today at work I wrote the following LOC (the real identities of b and b1 are confidential :)
b &&= b1; // meaning b = b && b1;
I stared at it for a couple of seconds and realized that there exists no such operator. Just to be sure, I clicked on compile and it failed. To be dead sure I consulted the standard.
Are there specific reasons that there are no such operators? I can think of some:
b &&= b1
andb = b && b1
may not be equivalent because of short-circuit evaluation of &&.- &&= is ugly
- &&= is rarely needed
I do not claim that it would be very useful to have such operators, no. I also don't claim that any or all of the three above reasons are not enough to refrain from creating that operator. My question is the following: is there maybe a much more serious reason which I am overseeing?
回答1:
I don't know why both the question and some of the answers mention short-circuiting behavior of the corresponding logical operators as a potential issue.
There's absolutely no short-circuit-related problems with defining &&=
and ||=
operators. They should be defined uniformly with +=
and other similar operators, meaning that a &&= b
should be equivalent to a = a && b
, but with a
being evaluated only once in &&=
version. This means in turn that b
is not evaluated at all if a
is originally zero. Easy.
So, the only reason they don't exist in the language is, well, "just because".
回答2:
I've wanted them before as well. I doubt that ugliness was by itself the determining factor, the short-circuiting behavior is the best argument against them I've heard so far.
Another contributing factor is that C is designed to operate close to the metal, pretty much all of the operators correspond directly to an instruction in major architectures. I don't think there is an instruction on x86, PPC, etc that directly implements b &&= b1;
回答3:
The biggest reason the operators don't exist is probably that K&R didn't think of any appealing way to define them. I've also sometimes wanted a ->= operator (ptr->=next would be equivalent to ptr = ptr->whatever).
A problem I think with &&= is that it's not obvious which of the following would be most useful, or which it's supposed to be:
if (lhs && rhs) lhs = 1; else lhs = 0; if (!rhs) lhs = 0; else lhs = !(!lhs)); if (lhs && !rhs) lhs = 0; if (!rhs) lhs = 0;The first variation is the one most clearly suggested by the syntax, but from a practical standpoint, if neither term is zero, it would often be more useful to leave the left-hand side alone than to set it to "1".
BTW, I've often wished for a variation of the comma operator which would evaluate the left side, save the value, then evaluate the right side, and return the value of the left side. Equivalent to:
int foo(int p1, int p2) return p1;except applicable to any type (p2 need not be the same type as p1, and could be void), and with a guaranteed left-to-right evaluation order. Would be very handy for things like post-increment indexing with a non-unit step, e.g., arr[ptr ~, ptr+=2]; or for certain types of data-swap operations, e.g., var1 = (var2 ~, var2=var1); etc.
回答4:
Because the result of a && b
is always 0
or 1
, I think the interpretation of this would only be unambiguous for the C99 _Bool
type. Since this didn't exist at the time C was created, this operator was then not included. And nowadays nobody easily adds another operator to C, since this would have an impact on all existing parsers.
回答5:
Personally I'd vote for the first rationale you went with. The boolean operators have short-circuit semantics, which would make for some really gnarly situations if translated into asignment operators. Either you don't make them short-circuit anymore, or you created some weird "optional" assignment operator (do the stuff on the right and assign in the result only if the value on the LHS is already non-zero). Either way you'd create subtle bugs because people would be expecting the other behavior.
回答6:
EDIT: Wrong language, but still applies
I agree with your three reasons, although there is one scenario where I have lamented the lack of this operator, when writing custom deserialization routines. In a couple of cases where an improperly serialized object wasn't really "exceptional" (and to prevent exception overhead in C# for very common failures), I would use boolean return values to signify whether a deserialization operation was successfull.
This code is completely theoretical, and Nested1, Nested2 and Nested3 are all structs:
public struct ComplexStruct
{
private Nested1 nested1;
private Nested2 nested2;
private Nested3[] nested3;
public bool Read(Reader reader)
{
bool ret = true;
int nested3Length = 0;
ret &&= nested1.Read(reader);
ret &&= nested2.Read(reader);
ret &&= reader.ReadInt32(ref nested3Length);
for(int i = 0; (ret && i < nested3Length); i++)
{
ret &&= nested3[i].Read(reader);
}
return ret;
}
}
来源:https://stackoverflow.com/questions/3962991/and-operators