Why no ||= and &&=
Author Message
Why no ||= and &&=

Quote:

> Apologies if this is a FAQ.

> We all use += and -= and occassionaqlly *= and /=
> If you're into embedded work you would use <<=, >>=
> |=, &= and ^=, but strangely enough after five or
> so years of coding C and C++, this is the first time
> I ever thought to use ||=  But hang on the compiler
> barfs! What gives?  It doesn't exist in the language!

> I'm just curious why there are no ||= and no &&=
> operators in the language?

> My only answer is that there probably isn't direct
> hardware support for these operations. There's
> direct hardware support for bitwise |= and the
> like, but given the language treats anything non-zero
> as true, there might not be direct hardware support
> for it in all architectures.

> It's either that or they didn't think they would need it.

> Opinions anyone?

The || and && are very special operators.  There is so called short
circuit rule.  If the left operand of || evaluates to 'true', the
right operand is not evaluated, and if the left operand of &&
evaluates to 'false', the right operand is not evaluated.  There is
no way to adhere to that rule with &&= and ||=.  Both sides have
to be evaluated.  I think that may be the reason.  Imagine you
write
a = a && b;
if a is false, it will stay false without evaluating b.  Whereas

a &&= b;

will cause b to be evaluated first, which breaks the short circuit
rule.  Same with ||=.

HTH

Victor
--

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=

Quote:

> I'm just curious why there are no ||= and no &&=
> operators in the language?

Probably because:

1. They would be rarely useful.

2. One of the special properties of || and && is that
they "short circuit" by not evaluating their second
argument if the result can be fully determined by
examining the value of the first argument, but this
property has no relevance for proposed ||= and &&=.
--
"In My Egotistical Opinion, most people's C programs should be indented six
feet downward and covered with dirt." -- Blair P. Houghton

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=
On 25 Sep 2000 19:30:15 -0400,

Quote:

> > I'm just curious why there are no ||= and no &&=
> > operators in the language?

> Probably because:

>   1. They would be rarely useful.

>   2. One of the special properties of || and && is that
>            they "short circuit" by not evaluating their second
>            argument if the result can be fully determined by
>            examining the value of the first argument, but this
>            property has no relevance for proposed ||= and &&=.

I don't actually agree with 1., but one could argue about that. Perl
defines both operators, and I use them quite a lot. Which leads me to
2.. Perl actually defines these operators to be exactly equivalent to
their more verbose counterparts, i.e.

A &&= B    <=>    A = A && B
A ||= B    <=>    A = A || B

and that includes the short-circuiting behaviour. In both cases B does
not get evaluated if the total value of the expression (A&&B or A||B)
can be determined by only evaluating the left argument to the
operator.

Of course, Perl is not C, and I am not trying to say that.

The question is now: _why_ is it not possible for C to define these
operators in the above way, and thus guarantee that short-circuiting
behaviour is correctly implemented? Does it have to do with definitions
of where sequence points occur? Or is it something else that makes
this impossible? Is there a difference between A -= B and A = A - B?

Martien
--
Martien Verbruggen              |
Interactive Media Division      | This matter is best disposed of from
Commercial Dynamics Pty. Ltd.   | a great height, over water.
NSW, Australia                  |

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=

Quote:

> On 25 Sep 2000 19:30:15 -0400,

> > > I'm just curious why there are no ||= and no &&=
> > > operators in the language?

> > Probably because:

> >   1. They would be rarely useful.

> >   2. One of the special properties of || and && is that
> >            they "short circuit" by not evaluating their second
> >            argument if the result can be fully determined by
> >            examining the value of the first argument, but this
> >            property has no relevance for proposed ||= and &&=.

> I don't actually agree with 1., but one could argue about that. Perl
> defines both operators, and I use them quite a lot. Which leads me to
> 2.. Perl actually defines these operators to be exactly equivalent to
> their more verbose counterparts, i.e.

> A &&= B    <=>    A = A && B
> A ||= B    <=>    A = A || B

> and that includes the short-circuiting behaviour. In both cases B does
> not get evaluated if the total value of the expression (A&&B or A||B)
> can be determined by only evaluating the left argument to the
> operator.

> Of course, Perl is not C, and I am not trying to say that.

> The question is now: _why_ is it not possible for C to define these
> operators in the above way, and thus guarantee that short-circuiting
> behaviour is correctly implemented? Does it have to do with
definitions
> of where sequence points occur? Or is it something else that makes
> this impossible? Is there a difference between A -= B and A = A - B?

There is no difference between A -= B and A = A - B.  They are EXACTLY
equivalent.  The value of A is taken once.  The value of B is taken
once.  The result is written once.  The difference is, like you said,
in the order of that evaluation.  It's unknown whether A is evaluated
before B or after.  There is no need in the order.  There would be if
&&= or ||= would be implemented.  Which makes it inconsistent.

I suppose the absence of the order requirement allows for greater
optimisation.  I think it is more important than to have the complete
list of compound assignments.

Victor
--

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=

Quote:

> > Apologies if this is a FAQ.

[snip]

>         a &&= b;

> will cause b to be evaluated first, which breaks the short circuit
> rule.  Same with ||=.

Of course, we could just specifiy that a &&=b is equivalent to a = a && b.
It wouldn't be that big a deal for a compiler to convert it automaticly.

--Steve

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=

Quote:

> [...]
> I am not trying to argue for the inclusion of these operators, I'm
> just wondering what the reasons were for them not being included.

You should post in comp.std.c++ then.  They're talking about the
C++ Standard.  Here, we're talking about Standard C++.  See the
difference?

Victor
--

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=

Quote:

>Apologies if this is a FAQ.
>I'm just curious why there are no ||= and no &&= operators in the language?

I've yet to encounter a situation where they'd be useful.

OTOH, every now and then a ^^ operator would beat
(a && !b) || (!a && b) where a and/or b are non-trivial
expressions.

--
For those who do, no explanation is necessary.
For those who don't, no explanation is possible.
For a good time, call the spammers at 888 514 6881

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=

Quote:

>> > OTOH, every now and then a ^^ operator would beat
>> > (a && !b) || (!a && b) where a and/or b are non-trivial
>> > expressions.

>> (!a != !b)

>Why not just (a!=b) ?

Consider int a = 1, b = 2. a logical xor b is false, but the expression would
evaluate true.

The ! operator converts its argument to 0 or 1 as appropriate, so the
expression works for any a and b...
--
For those who do, no explanation is necessary.
For those who don't, no explanation is possible.
For a good time, call the spammers at 888 514 6881

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=

Quote:

> > On 25 Sep 2000 19:30:15 -0400 in comp.lang.c++,

> > >> I'm just curious why there are no ||= and no &&=
> > >> operators in the language?

> > >Probably because:

> > > 1. They would be rarely useful.

> > Hah!  Then explain the comma operator.

> It's useful when you have multiple initializations in a for statement.

The initialisations?  Could you give an example, please?

Victor
--

Fri, 14 Mar 2003 03:00:00 GMT
Why no ||= and &&=
Apologies if this is a FAQ.

We all use += and -= and occassionaqlly *= and /=
If you're into embedded work you would use <<=, >>=
|=, &= and ^=, but strangely enough after five or
so years of coding C and C++, this is the first time
I ever thought to use ||=  But hang on the compiler
barfs! What gives?  It doesn't exist in the language!

I'm just curious why there are no ||= and no &&=
operators in the language?

My only answer is that there probably isn't direct
hardware support for these operations. There's
direct hardware support for bitwise |= and the
like, but given the language treats anything non-zero
as true, there might not be direct hardware support
for it in all architectures.

It's either that or they didn't think they would need it.

Opinions anyone?

Tom.

Sat, 15 Mar 2003 07:25:48 GMT
Why no ||= and &&=

Quote:

> > I'm just curious why there are no ||= and no &&=
> > operators in the language?

> Probably because:

>         1. They would be rarely useful.

I agree with this as it took me more than five years to need it.
What I'm doing is running an operation on each element of an
array. I need to know if at least one of them returned true.
The first idea was to do this:

bool changed = false;
for (int i = 0; i < length; i++)
{
changed ||= array[i].operation();

Quote:
}

>         2. One of the special properties of || and && is that
>            they "short circuit" by not evaluating their second
>            argument if the result can be fully determined by
>            examining the value of the first argument, but this
>            property has no relevance for proposed ||= and &&=.

I agree. After the above loop failed to compile I changed it to this:
bool changed = false;
for (int i = 0; i < length; i++)
{
changed = changed || array[i].operation();

Quote:
}

As you can see as soon as one changes the rest get short-circuited.

It could be possible to have a ||= which didn't execute the other
side if it was already true.
e.g. for my loop it could check the value of changed before
deciding if it wanted to do the operation.

Tom.

Sat, 15 Mar 2003 07:53:44 GMT
Why no ||= and &&=

Quote:

> I agree. After the above loop failed to compile I changed it to this:
> bool changed = false;
> for (int i = 0; i < length; i++)
> {
>     changed = changed || array[i].operation();
> }

It's cleaner to just terminate the loop once changed becomes true:

for (int i = 0; i < length && !changed; i++)
changed = array[i].operation();

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Contributing Editor, C/C++ Users Journal (http://www.cuj.com)

Sat, 15 Mar 2003 08:26:40 GMT
Why no ||= and &&=

Quote:

> > > I'm just curious why there are no ||= and no &&=
> > > operators in the language?

> > Probably because:

> >         1. They would be rarely useful.

> I agree with this as it took me more than five years to need it.
> What I'm doing is running an operation on each element of an
> array. I need to know if at least one of them returned true.
> The first idea was to do this:

> bool changed = false;
> for (int i = 0; i < length; i++)
> {
>     changed ||= array[i].operation();
> }

| and || differ in the following ways:

| always evaluates both operands and returns an integral type which is
the bit-wise or of the two operands.

|| only evaluates the right hand operand if the left hand operand is 0,
and it returns a bool type which is true if either of its operands is
non-zero, otherwise false.

When the destination of the expression is a bool there is no difference
in the final result of | and ||.  The only question therefore is whether
or not the right hand operand is evaluated.

Are you saying that you do not want the method operation called if
changed is already true?  In that case you could achieve that exact
result more efficiently by:

for (int i = 0; i < length; i++)
{
if (changed |= array[i].operation())
break;

Quote:
}

--

34 Palomino Dr.
K2M 1M1
+1-613-592-9438

Sat, 15 Mar 2003 08:31:17 GMT
Why no ||= and &&=

Quote:

> > I agree with this as it took me more than five years to need it.
> > What I'm doing is running an operation on each element of an
> > array. I need to know if at least one of them returned true.
> > The first idea was to do this:

> > bool changed = false;
> > for (int i = 0; i < length; i++)
> > {
> >     changed ||= array[i].operation();
> > }

> Are you saying that you do not want the method operation called if
> changed is already true?  In that case you could achieve that exact
> result more efficiently by:

I can see the confusion, because I used the loop for two different explanations.

For my case I must do the operation on all elements, the operation returns
if any of the data changed during the operation. I need to know if anything
changed in an _any_ of the operations. I ended up changing it to:
changed = array[i].operation() || changed;

I then used my loop as a reasoning of how I thought an ||= should work, which
for my case would have only done the operation until it changed, which isn't
what I required. Plus if this was the desired behaviour then your suggestion
about terminating based on the return value would make more sense.

Tom.

Sat, 15 Mar 2003 08:48:13 GMT
Why no ||= and &&=
On Mon, 25 Sep 2000 17:09:48 -0700,

Quote:

> > On 25 Sep 2000 19:30:15 -0400,

> > >   2. One of the special properties of || and && is that
> > >            they "short circuit" by not evaluating their second
> > >            argument if the result can be fully determined by
> > >            examining the value of the first argument, but this
> > >            property has no relevance for proposed ||= and &&=.

> > The question is now: _why_ is it not possible for C to define these
> > operators in the above way, and thus guarantee that short-circuiting
> > behaviour is correctly implemented? Does it have to do with definitions
> > of where sequence points occur? Or is it something else that makes
> > this impossible? Is there a difference between A -= B and A = A - B?

> There is no difference between A -= B and A = A - B.  They are EXACTLY
> equivalent.  The value of A is taken once.  The value of B is taken
> once.  The result is written once.  The difference is, like you said,
> in the order of that evaluation.  It's unknown whether A is evaluated
> before B or after.  There is no need in the order.  There would be if
> &&= or ||= would be implemented.  Which makes it inconsistent.

> I suppose the absence of the order requirement allows for greater
> optimisation.  I think it is more important than to have the complete
> list of compound assignments.

I just checked a copy of the C99 standard (draft) that Igot from
soneone here. The section on assignment operators (6.5.16) states
explicitly:

[#4] The order of evaluation of the operands is unspecified.
If an attempt is made to modify the result of an  assignment
operator  or to access it after the next sequence point, the
behavior is undefined.

The section on logical OR (6.5.14)

[#4]  Unlike  the  bitwise  |  operator,  the  ||   operator
guarantees  left-to-right  evaluation;  there  is a sequence
point after the evaluation of the  first  operand.   If  the
first  operand  compares unequal to 0, the second operand is
not evaluated.

The combination of these two do indeed make it impossible to implement
||= or &&= as part of the set of assignment operators. But, since &&
and && have special provisos attached to them, that guarantee a
sequence point after the left operand, would it be impossible at all
to define ||= and &&= as special assignment operators that have a
sequence point after their left operand? I can't logically see any
reason to not do that. There may however have been more practical
reasons which have already been mentioned: 1. It's not useful enough;
and 2. It may influence optimisation. Apart from that, there may have
been reasons that the inclusion of these would simply not be elegant,
because you'd have to allow at least two assignment operators with
different behaviour than the others. On the other hand, && and ||
already behave differently from other operators...

I am not trying to argue for the inclusion of these operators, I'm
just wondering what the reasons were for them not being included.

Martien
--
Martien Verbruggen              |
Interactive Media Division      | That's not a lie, it's a
Commercial Dynamics Pty. Ltd.   | terminological inexactitude.
NSW, Australia                  |

Sat, 15 Mar 2003 08:48:06 GMT

 Page 1 of 2 [ 25 post ] Go to page: [1] [2]

Relevant Pages