www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - dmd warning request: warn for bitwise OR in conditional

reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
We've been bitten by the following bug recently in C code:

     uint flag = 0x1;
     uint flags;

     if (flags | flag) {
         dout.writefln("oops");
     }

The programmer intended &.

It is (almost?) always an error to use | in a conditional. At least the 
conditional in the above code is always true; so dmd could generate a 
warning. (Yes, I used -w.)

Ali
Jan 21 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Ali:
 We've been bitten by the following bug recently in C code:
      uint flag = 0x1;
      uint flags;
 
      if (flags | flag) {
          dout.writefln("oops");
      }
 
 The programmer intended &.
 It is (almost?) always an error to use | in a conditional.
Why do you think it's almost always an error? I have seen more than one time a related bug in C code (once written by me and other times written by other people): if (foo & bar) {... instead of: if (foo && bar) {... To avoid this kind of bug you can disallow integers in conditionals (requiring something like a ! or == 0 to turn an integral value in a boolean) as Java (and partially Pascal), or you can remove the && || from the language and replace them with "and" and "or", so it becomes easy to tell them apart from bitwise operators. I like the second way. Bye, bearophile
Jan 21 2010
parent reply Yigal Chripun <yigal100 gmail.com> writes:
On 22/01/2010 09:59, bearophile wrote:
 Ali:
 We've been bitten by the following bug recently in C code: uint
 flag = 0x1; uint flags;

 if (flags | flag) { dout.writefln("oops"); }

 The programmer intended&. It is (almost?) always an error to use |
 in a conditional.
Why do you think it's almost always an error? I have seen more than one time a related bug in C code (once written by me and other times written by other people): if (foo& bar) {... instead of: if (foo&& bar) {... To avoid this kind of bug you can disallow integers in conditionals (requiring something like a ! or == 0 to turn an integral value in a boolean) as Java (and partially Pascal), or you can remove the&& || from the language and replace them with "and" and "or", so it becomes easy to tell them apart from bitwise operators. I like the second way. Bye, bearophile
Instead of renaming the boolean ops they should simply be removed. The type system gives you all the required information to know what to do without needlessly duplicating the syntax: uint a, b; // init to whatever bool c, d; // ditto auto r1 = a AND b; // a & b auto r2 = c AND d; // c && d ... AND stands for whatever *single* syntax is chosen for this. the compiler will implement the boolean version with lazy evaluation and the unsigned integral versions (uint, ulong, ...) with eager evaluation. If someone really want to use Boolean ops on numbers [s]he could always do that explicitly: cast(bool)myNum AND whatever
Jan 23 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Yigal Chripun:
 If someone really want to use Boolean ops on numbers [s]he could always 
 do that explicitly:
 cast(bool)myNum AND whatever
Thanks, but no thanks. Bye, bearophile
Jan 23 2010
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Yigal Chripun" <yigal100 gmail.com> wrote in message 
news:hjek8e$4j0$1 digitalmars.com...
 uint a, b; // init to whatever
 bool c, d; // ditto

 auto r1 = a AND b; //  a & b
 auto r2 = c AND d; // c && d
 ...
 AND stands for whatever *single* syntax is chosen for this.
Yuck, that amounts to language-enforced operator overloading abuse, just like the common mis-design of overloading '+' to mean both 'add' and 'concat'.
Jan 23 2010
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
Nick Sabalausky wrote:
 "Yigal Chripun" <yigal100 gmail.com> wrote in message 
 news:hjek8e$4j0$1 digitalmars.com...
 uint a, b; // init to whatever
 bool c, d; // ditto

 auto r1 = a AND b; //  a & b
 auto r2 = c AND d; // c && d
 ...
 AND stands for whatever *single* syntax is chosen for this.
Yuck, that amounts to language-enforced operator overloading abuse, just like the common mis-design of overloading '+' to mean both 'add' and 'concat'.
That exists for the assignment operator too (which happens to be a misnomer). lhs = rhs; may mean, without any user overloading: a) assign (destroy the value of lhs and copy the value of rhs) b) let lhs provide access to the same object that rhs is providing access to (as a side effect, if lhs was the single reference to lhs's object, then the object may be destroyed in the future) The behavior depends on whether the type is a value type or a reference type. Ali
Jan 23 2010
parent "Nick Sabalausky" <a a.a> writes:
"Ali Çehreli" <acehreli yahoo.com> wrote in message 
news:hjg2fo$d28$1 digitalmars.com...
 Nick Sabalausky wrote:
 "Yigal Chripun" <yigal100 gmail.com> wrote in message 
 news:hjek8e$4j0$1 digitalmars.com...
 uint a, b; // init to whatever
 bool c, d; // ditto

 auto r1 = a AND b; //  a & b
 auto r2 = c AND d; // c && d
 ...
 AND stands for whatever *single* syntax is chosen for this.
Yuck, that amounts to language-enforced operator overloading abuse, just like the common mis-design of overloading '+' to mean both 'add' and 'concat'.
That exists for the assignment operator too (which happens to be a misnomer). lhs = rhs; may mean, without any user overloading: a) assign (destroy the value of lhs and copy the value of rhs) b) let lhs provide access to the same object that rhs is providing access to (as a side effect, if lhs was the single reference to lhs's object, then the object may be destroyed in the future) The behavior depends on whether the type is a value type or a reference type. Ali
I've always seen "b" as just simply "a) assign" where the values being copied/destroyed are references instead of, say, chars or floats. Conversely, you can "a) assign" an int that's intended as an index into a collection and doing so amounts to "b". So that "a" and "b" essentially *are* the same.
Jan 23 2010
prev sibling parent Yigal Chripun <yigal100 gmail.com> writes:
On 23/01/2010 20:10, Nick Sabalausky wrote:
 "Yigal Chripun"<yigal100 gmail.com>  wrote in message
 news:hjek8e$4j0$1 digitalmars.com...
 uint a, b; // init to whatever
 bool c, d; // ditto

 auto r1 = a AND b; //  a&  b
 auto r2 = c AND d; // c&&  d
 ...
 AND stands for whatever *single* syntax is chosen for this.
Yuck, that amounts to language-enforced operator overloading abuse, just like the common mis-design of overloading '+' to mean both 'add' and 'concat'.
"No operator was abused during the making of this post"... unlike the string concat. case, both the bit ops and the bool ops have the exact same semantics (OR, AND, NOT) and the only difference is the scale . This is already represented by the type system and there is no need to repeat yourself a-la Java: Foo foo = new Foo(); // is this really a Foo? in the same spirit of things, no-one argues for a different addition op for each integral type: int a = 2 + 4; long b = 2000000 ++ 400000000000; // LOOOOONG addition it ain't assembly language. Also, it prevents common bugs and makes for more readable code. In the same vain, I'd be willing to remove other shortcuts that are come causes of bugs, like the assignment inside the if condition and not requiring explicit check in if condition. "if (foo is null)" instead of "if (foo)". Last thing, Stop with the moronic "oh my god, I need to type a few more characters" attitude. (Yes, bearophile, that's you.) FACT - code is read 1000 times more than it's written. readability IS important. No, xfoo is NOT a legit name for a function, call it lazyFoo if you want to emphasize its laziness. are you still trying to save 3 bytes in the age of cheap Tera-byte HDDs? In the same spirit, stop removing f*cking vowels from words. You ain't coding in Hebrew.
Jan 30 2010
prev sibling parent Daniel Murphy <yebbliesnospam gmail.com> writes:
bearophile Wrote:

 Ali:
 We've been bitten by the following bug recently in C code:
      uint flag = 0x1;
      uint flags;
 
      if (flags | flag) {
          dout.writefln("oops");
      }
 
 The programmer intended &.
 It is (almost?) always an error to use | in a conditional.
Why do you think it's almost always an error? I have seen more than one time a related bug in C code (once written by me and other times written by other people): if (foo & bar) {... instead of: if (foo && bar) {... To avoid this kind of bug you can disallow integers in conditionals (requiring something like a ! or == 0 to turn an integral value in a boolean) as Java (and partially Pascal), or you can remove the && || from the language and replace them with "and" and "or", so it becomes easy to tell them apart from bitwise operators. I like the second way. Bye, bearophile
The difference between those two use cases is that (a & b) is commonly used to check if a bit has been set. (a | b) yields the same result as (a || b) when used in a conditional. Is there any valid use for (a | b) as a 'truth' value? Daniel
Jan 22 2010