digitalmars.D - &&=, ||= ?
- z gg.com (11/11) Jul 11 2005 For integer type, we have (+=, -=, *= /=), e.g.
- Mike Parker (2/20) Jul 11 2005 What exactly would &&= do? I'm not grokking the assignment part of it.
- clayasaurus (5/26) Jul 11 2005 I assume it would mean this... (using bool/bit bob)
- Hasan Aljudy (8/26) Jul 11 2005 I think it's just that nobody every needed it or thought about it .. or
- Uwe Salomon (9/20) Jul 11 2005 Yes. For the "bit" type (a && b) and (a & b) are the same, as it is only...
-
Stewart Gordon
(22/31)
Jul 14 2005
- Uwe Salomon (9/17) Jul 14 2005 if (b) -- first access to b
- Uwe Salomon (6/8) Jul 14 2005 Though i must add that the generated machine code could be very similar ...
-
Stewart Gordon
(14/33)
Jul 14 2005
- Uwe Salomon (33/48) Jul 14 2005 Hmm, i don't know how to explain. Perhaps "evaluate" is the wrong word? ...
-
Stewart Gordon
(17/36)
Jul 15 2005
- Greg Smith (37/71) Jul 18 2005 /// I'm discussing C: AFIK applies equally to D
- Greg Smith (21/50) Jul 18 2005 the 'evaluated once' only is meaningful when the LHS has an address
- Derek Parnell (18/75) Jul 18 2005 LOL... In 'my world' both these would not be allowed because you can't O...
- Uwe Salomon (4/7) Jul 18 2005 Hmm. Your world seems to be cluttered with parentheses and casts... Not ...
- Derek Parnell (13/20) Jul 18 2005 LOL.
- Uwe Salomon (14/21) Jul 18 2005 I have often seen things like this when dealing with return values or
For integer type, we have (+=, -=, *= /=), e.g. i += j; For bool type, why we don't have (&&=, ||=) ? void f() { bool b, c; b &&= c; } $ dmd -c aae.d aae.d:5: expression expected, not '=' aae.d:5: found 'c' when expecting ';' following 'statement' Is there a reason for this?
Jul 11 2005
z gg.com wrote:For integer type, we have (+=, -=, *= /=), e.g. i += j; For bool type, why we don't have (&&=, ||=) ? void f() { bool b, c; b &&= c; } $ dmd -c aae.d aae.d:5: expression expected, not '=' aae.d:5: found 'c' when expecting ';' following 'statement' Is there a reason for this?What exactly would &&= do? I'm not grokking the assignment part of it.
Jul 11 2005
Mike Parker wrote:z gg.com wrote:I assume it would mean this... (using bool/bit bob) bob = (bob && a); would become bob &&= a;For integer type, we have (+=, -=, *= /=), e.g. i += j; For bool type, why we don't have (&&=, ||=) ? void f() { bool b, c; b &&= c; } $ dmd -c aae.d aae.d:5: expression expected, not '=' aae.d:5: found 'c' when expecting ';' following 'statement' Is there a reason for this?What exactly would &&= do? I'm not grokking the assignment part of it.
Jul 11 2005
z gg.com wrote:For integer type, we have (+=, -=, *= /=), e.g. i += j; For bool type, why we don't have (&&=, ||=) ? void f() { bool b, c; b &&= c; } $ dmd -c aae.d aae.d:5: expression expected, not '=' aae.d:5: found 'c' when expecting ';' following 'statement' Is there a reason for this?I think it's just that nobody every needed it or thought about it .. or something like that! we don't work with booleans and manipulate thier values much .. we just use them for control structures i.e. if .. while .. etc. only time I work with booleans is as flags .. the most radical manipulation I would do is toggling them flag = !flag;
Jul 11 2005
On Tue, 12 Jul 2005 03:25:34 +0200, <z gg.com> wrote:For integer type, we have (+=, -=, *= /=), e.g. i += j; For bool type, why we don't have (&&=, ||=) ? void f() { bool b, c; b &&= c; } $ dmd -c aae.d aae.d:5: expression expected, not '=' aae.d:5: found 'c' when expecting ';' following 'statement' Is there a reason for this?Yes. For the "bit" type (a && b) and (a & b) are the same, as it is only a single bit. && exists only because integers have more than one bit, but all nonzero values are interpreted as true. Thus, if you want to work with bits, just use &=, |= etc. With integers you have to use the long form, because all op= variants are guaranteed to evaluate the lvalue only once. This is not possible for &&= with, say, an uint. Ciao uwe
Jul 11 2005
Uwe Salomon wrote:On Tue, 12 Jul 2005 03:25:34 +0200, <z gg.com> wrote:<snip><snip>For bool type, why we don't have (&&=, ||=) ?Yes. For the "bit" type (a && b) and (a & b) are the same, as it is only a single bit. && exists only because integers have more than one bit, but all nonzero values are interpreted as true. Thus, if you want to work with bits, just use &=, |= etc.Unless you want the rvalue to be lazily evaluated. Really b &&= c; should be equivalent to if (b) b = c; and similarly b ||= c; equivalent to if (!b) b = c;With integers you have to use the long form, because all op= variants are guaranteed to evaluate the lvalue only once. This is not possible for &&= with, say, an uint.What do you mean by this? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jul 14 2005
Look at the code equivalent you have given yourself:With integers you have to use the long form, because all op= variants are guaranteed to evaluate the lvalue only once. This is not possible for &&= with, say, an uint.What do you mean by this?Really b &&= c; should be equivalent to if (b) b = c;if (b) -- first access to b b = c -- second access to b But the operators += -= |= etc. should evaluate b only once, not twice. By the way, b &&= c should mean something like this: if (b) b = (c != 0); Ciao uwe
Jul 14 2005
But the operators += -= |= etc. should evaluate b only once, not twice.Though i must add that the generated machine code could be very similar if the compiler does not put the variables in the registers. Both of them load a variable from the stack into a register, change it and write it back to the stack. Ciao uwe
Jul 14 2005
Uwe Salomon wrote:I still don't see how it relates.Look at the code equivalent you have given yourself:With integers you have to use the long form, because all op= variants are guaranteed to evaluate the lvalue only once. This is not possible for &&= with, say, an uint.What do you mean by this?<snip> Exactly. I was using b to refer to the evaluation, rather than the expression. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.Really b &&= c; should be equivalent to if (b) b = c;if (b) -- first access to b b = c -- second access to b But the operators += -= |= etc. should evaluate b only once, not twice.
Jul 14 2005
I still don't see how it relates.Hmm, i don't know how to explain. Perhaps "evaluate" is the wrong word? Look into http://www.digitalmars.com/d/expression.html#AssignExpression If you have this expression: b = b + c; Compiled it will look somehow like this: make a copy of b add c to the copy store the result to b The other variant: b += c; Looks like this when compiled: add c to b See the difference? In the first variant b is "evaluated" twice. This is not as important if you use integers, as the resulting machine code will be the same if they are stored on the stack: mov EAX, b add EAX, c mov b, EAX But if you use user-defined data types, this will be different: b = b.opAdd(c); // versus b.opAddAssign(c); The second one will often be much faster, as the implementation for opAdd will look like this: Type opAdd(Type other) { Type copy = *this; copy.opAddAssign(other); return copy; } Ciao uwe<snip> Exactly. I was using b to refer to the evaluation, rather than the expression.Really b &&= c; should be equivalent to if (b) b = c;if (b) -- first access to b b = c -- second access to b But the operators += -= |= etc. should evaluate b only once, not twice.
Jul 14 2005
Uwe Salomon wrote: <snip>If you have this expression: b = b + c; Compiled it will look somehow like this: make a copy of b add c to the copy store the result to b The other variant: b += c; Looks like this when compiled: add c to b See the difference? In the first variant b is "evaluated" twice.<snip> Unless you add the words "except that b is only evaluated once" to the first explanation. Indeed, this is how it's explained in the spec if you care to read it. Moreover, even if &&= ||= were a special case of being not so easily explainable in words, it would still be equally implementable. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Jul 15 2005
/// I'm discussing C: AFIK applies equally to D b += c; // LHS evaluated only once. If 'b' is a simple (non-class) variable, there's no difference between "b += c" and "b = b + c". The difference is important when there is a calculation involved in finding the address of the lvalue, and that calculation has (or may have) side-effects. *get_ptr(x) += 2; vs. *get_ptr(x) = *get_ptr(x) + 2; the first example makes only 1 call to get_ptr(), the second will make two. The order in which the two calls are made is not specified by the C language. Or, a[ i++ ] += 3; // NOT the same as a[ i++ ] = a[i++] + 3; (the second example is improper C, since the two references to i are not well-defined relative to the modifications of i) 'calculating' the address of a local variable by adding a constant to the frame pointer doesn't count, since the result cannot change during the execution of a single statement; the compiler is perfectly free to do that once for 'b = b+c', or do it twice for 'b+=c'. [Note: I remember some cheesy old C compilers which generated code directly out of the parser, such that 'b+=c' would be smaller than 'b = b + c', since the compiler calculated the address of local 'b' twice in the second case. That is not a language issue, it's a cheesy compiler issue. The same compiler generated less code for '++i;' than for 'i++;', enough said ] Another example: arr[i+2] += 4; arr[i+2] = arr[i+2] + 4; Both have the same effect. They may generate different code, depending on the compiler. But they may not. The distinction between + and += doesn't extend to that. Stewart Gordon wrote:Uwe Salomon wrote: <snip>If you have this expression: b = b + c; Compiled it will look somehow like this: make a copy of b add c to the copy store the result to b The other variant: b += c; Looks like this when compiled: add c to b See the difference? In the first variant b is "evaluated" twice.<snip> Unless you add the words "except that b is only evaluated once" to the first explanation. Indeed, this is how it's explained in the spec if you care to read it. Moreover, even if &&= ||= were a special case of being not so easily explainable in words, it would still be equally implementable. Stewart.
Jul 18 2005
Uwe Salomon wrote:the 'evaluated once' only is meaningful when the LHS has an address which must be calculated, and its calculation may have side-effects. The calculation will only be done once. {bit * bptr = &b; // the 'evaluated once' means this if (*bptr) *bptr = (c != 0); } I remember a discussion about &&= and ||= about 20 years ago on comp.lang.c, when the ISO standard was being drafted. Yes, they could be done, but they're rather weird; what about int b = 4; int c = ...; // doesn't matter b ||= c; should this leave 'b' as 4, since the evaluation was short-circuited due to b!=0 ?? This is what has been proposed in this thread. Or should it set 'b' to 1, which is what b = b||c does? no thanks. Such an operator would be misunderstood out of proportion to its usefulness, no matter how it is defined. - gregLook at the code equivalent you have given yourself:With integers you have to use the long form, because all op= variants are guaranteed to evaluate the lvalue only once. This is not possible for &&= with, say, an uint.What do you mean by this?Really b &&= c; should be equivalent to if (b) b = c;if (b) -- first access to b b = c -- second access to b But the operators += -= |= etc. should evaluate b only once, not twice. By the way, b &&= c should mean something like this: if (b) b = (c != 0);
Jul 18 2005
On Mon, 18 Jul 2005 17:02:24 -0400, Greg Smith wrote:Uwe Salomon wrote:LOL... In 'my world' both these would not be allowed because you can't OR non-booleans. This would be okay ... bool b,c; . . . b = b || c; But this would be just silly... int b,c; . . . b = b || c; You could do this though ... b = cast(int) ((b != 0) || (c != 0)); But I digress ... D isn't my perfect language, nor will it ever be. -- Derek Parnell Melbourne, Australia 19/07/2005 7:46:13 AMthe 'evaluated once' only is meaningful when the LHS has an address which must be calculated, and its calculation may have side-effects. The calculation will only be done once. {bit * bptr = &b; // the 'evaluated once' means this if (*bptr) *bptr = (c != 0); } I remember a discussion about &&= and ||= about 20 years ago on comp.lang.c, when the ISO standard was being drafted. Yes, they could be done, but they're rather weird; what about int b = 4; int c = ...; // doesn't matter b ||= c; should this leave 'b' as 4, since the evaluation was short-circuited due to b!=0 ?? This is what has been proposed in this thread. Or should it set 'b' to 1, which is what b = b||c does? no thanks. Such an operator would be misunderstood out of proportion to its usefulness, no matter how it is defined.Look at the code equivalent you have given yourself:With integers you have to use the long form, because all op= variants are guaranteed to evaluate the lvalue only once. This is not possible for &&= with, say, an uint.What do you mean by this?Really b &&= c; should be equivalent to if (b) b = c;if (b) -- first access to b b = c -- second access to b But the operators += -= |= etc. should evaluate b only once, not twice. By the way, b &&= c should mean something like this: if (b) b = (c != 0);
Jul 18 2005
LOL... In 'my world' both these would not be allowed because you can't OR non-booleans. b = cast(int) ((b != 0) || (c != 0));Hmm. Your world seems to be cluttered with parentheses and casts... Not sure if this is the way to go. :) Ciao uwe
Jul 18 2005
On Tue, 19 Jul 2005 07:41:02 +0200, Uwe Salomon wrote:LOL. My point however was that the OP was dealing with numbers, and why does anybody want to logically-or numbers? Booleans I can understand, but numbers? Doesn't make sense to me. It as silly as asking for the square root of "ABC". The point with casts and parenthesizes, is that if you really, really needed to do this, then your code should have obvious flashing warning signs around it. -- Derek Melbourne, Australia 19/07/2005 3:48:07 PMLOL... In 'my world' both these would not be allowed because you can't OR non-booleans. b = cast(int) ((b != 0) || (c != 0));Hmm. Your world seems to be cluttered with parentheses and casts... Not sure if this is the way to go. :)
Jul 18 2005
My point however was that the OP was dealing with numbers, and why does anybody want to logically-or numbers? Booleans I can understand, but numbers? Doesn't make sense to me. It as silly as asking for the square root of "ABC".I have often seen things like this when dealing with return values or lengths. API functions from Windows or libc or whatever often return a status code that is of type int. If zero is used to signal an error, and a nonzero value for success, you can write things like this: if (write(f, "xyz") && read(g, &i)) printf("success!"); The same goes for pointers and lengths: if (someObj) delete someObj; Though i must admit that i often write the full expressions because i don't like this kind of abbreviations.The point with casts and parenthesizes, is that if you really, really needed to do this, then your code should have obvious flashing warning signs around it.Nah, that's too much. Ciao uwe
Jul 18 2005