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
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
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
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
"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'.
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
"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.
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.