Bug 3847 – To avoid a C code bug

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-02-23T18:11:00Z
Last change time
2015-06-09T01:27:38Z
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2010-02-23T18:11:52Z
What does this D2 program print, and why? import std.stdio; bool thirdElementIsThree(int[] a) { return a.length >= 3 & a[2] == 3; } void main() { int[][] tests = [[6, 5, 4, 3, 2, 1], [1, 2], [1, 2, 3], [1, 2, 3, 4 ], [1]]; int n = 0; try { int i = 0; while (true) { if (thirdElementIsThree(tests[i++])) n++; } } catch(Error e) { // No more tests to process } writeln(n); // prints? } Using 'and' and 'or' instead of && and || helps reduce some possible programmer mistakes, because the programmer may write & or | and the compiler may not catch the mistake. Using those keyword (as in Python and many other languages) avoids such mistakes, and C programmer will not be confused by this change because the || and && becomes deprecated, as the 'l' suffix for numbers. 'and' and 'or' are also quite less cryptic than && and || symbols. && and || can be kept to keep C compatibility, but their usage can be discouraged in new normal D2 code. In real code it happens to write a & where you want to write &&, this is not an uncommon bug.
Comment #1 by ellery-newcomer — 2010-02-23T18:39:12Z
(In reply to comment #0) > What does this D2 program print, and why? > > > import std.stdio; > > bool thirdElementIsThree(int[] a) { > return a.length >= 3 & a[2] == 3; > } > > void main() { > int[][] tests = [[6, 5, 4, 3, 2, 1], > [1, 2], > [1, 2, 3], > [1, 2, 3, 4 ], > [1]]; > int n = 0; > > try { > int i = 0; > while (true) { > if (thirdElementIsThree(tests[i++])) > n++; > } > } catch(Error e) { > // No more tests to process > } > > writeln(n); // prints? > } Ooh! Ooh! I know! it segfaults because the loop doesn't terminate and eventually test[i++] attempts to access memory not allocated to that process! We're talking about things that would happen in C, right? Personally, I prefer and,or, etc over &&,||, etc because they take less finger gymnastics to type.
Comment #2 by shro8822 — 2010-02-23T20:24:24Z
In order of preference: 1: close a won't fix, 'is' and 'in' are bad enought,we don't need more keyword-as-operators 2: replace the less common bitwise operators '&' and '|' with 'and' & 'or'
Comment #3 by smjg — 2010-02-27T13:02:48Z
(In reply to comment #2) > 2: replace the less common bitwise operators '&' and '|' with 'and' & 'or' I somehow think that would confuse people, who generally expect 'and' and 'or' to be logical rather than bitwise. Though people coming from certain M$ Basic backgrounds have instead to deal with boolean true being 1 rather than -1.
Comment #4 by bearophile_hugs — 2010-05-03T10:45:16Z
and, or operators exist in C++: http://en.wikipedia.org/wiki/Iso646.h This C++ code compiles: #include "stdio.h" #include "stdlib.h" int main() { bool a = atoi("1"); bool b = atoi("1"); bool c = atoi("0"); printf("%d\n", (a and b) or c); }
Comment #5 by bugzilla — 2010-05-03T11:00:26Z
C++ has had the 'and' and 'or' alternate keywords for well over a decade. To my knowledge, nobody uses them, and few C++ programmers even know they exist. It's a failure. Therefore, I don't think it is a good idea to adopt them.
Comment #6 by destructionator — 2010-05-03T11:26:55Z
I think we should replace all the operators to avoid bugs. = should be changed to SET_TO == should be changed to IS_EQUAL_TO + should be changed to ADD - should be SUBTRACT a++ should be INCREMENT_AND_RETURN_OLD_VALUE ++a should be INCREMENT and so on. This way, the user's intention is always clear because he has to type out the value. Each has a different length and/or starts with a different letter to aid in autocomplete and noticing if the autocomplete picks the wrong one. Check out how clear this code is: for(a SET_TO 0 TERMINATE_INITIALIZATION a LESS_THAN 10 TERMINATE_CONTINATION_CONDITION INCREMENT a) { if(a LESS_THAN 5 AND a REMAINDER_AFTER_VALUE_DIVIDED_BY 2 IS_EQUAL_TO 0) writefln("%INTEGER_FORMAT", a); } Amazing and guaranteed to be bug free! ---------- So seriously now, how many times have you written & when you meant && and not noticed it quickly? If anything were to change here, I'd say the rules on implicit conversion to boolean should he changed, not the operator. (And, ideally, the bitwise precidence!) Then you'd do bool f(int x) { return x & 1; // compile error - can't implicitly cast int to bool } bool f(int x) { return (x & 1) == 1; // works } But I doubt this is a problem often enough to warrant any change.
Comment #7 by bearophile_hugs — 2010-05-03T12:10:07Z
In C++ no one used them. But it can be just a matter of nudging D programmers in the right direction with the style guide and commonly accepted idioms for writing D code fist, and few years from now with warnings of deprecation of the bug-prone || &&, before removing them from some future version. Python uses the "and" and "or" and shows how better they are: they just look better and more natural, are simpler and faster to type, they make the code less visually noisy, are written as they are read aloud, and they avoid some bugs like the one I've shown at the top (the presence of such bugs can be seen from the fact that both the Gimpel lint warns about an error like the one of the original top, and recent GCC versions have warning for such probably erroneous usage of bitwise operators). It's a change for the better.
Comment #8 by braddr — 2010-05-03T12:50:11Z
'and' is isn't particularly less ambiguous than && vs &. The use of a word doesn't help tell me logical vs bitwise. Additionally, if you're going to word-ize some of the logical operators, you'd better do that for all of them.. so don't forget exclusiveor and equals and lessthan and... Rather than let this ticket become a debated endlessly ticket, given Walter's response, I suggest it be closed as wontfix aka notabug.
Comment #9 by ary — 2010-05-03T12:58:09Z
'and' and 'or' also help with readability. The thing is, you can make mistakes with && and &. You can't make mistakes with 'and' and '&'. Nobody used 'and' and 'or' as variables or function names so I don't think it's a problem at all to add them as synonymous to && and ||.
Comment #10 by bugzilla — 2010-05-03T21:14:14Z
Just today on reddit I saw: "I'm a bit embarrassed that after 10 years with C++ I learned something from a 12-bullet post intended for those new to the language. I'm amazed to learn that C++ has those built-in arithmetic keyword operators. I can't really see myself using them -- for various reasons -- but it's an interesting tidbit nonetheless." http://www.reddit.com/r/programming/comments/bzcgn/c_for_c_programmers_part_12_the_nonoo_features/ It sums up the typical attitude I've seen towards them.
Comment #11 by bearophile_hugs — 2010-09-20T17:24:18Z
(In reply to comment #10) > It sums up the typical attitude I've seen towards them. Some C++ programmers don't even know about 'and' and 'or' because the C++ compilers do nothing to suggest, encourage or force the usage of those more readable and less bug-prone operators. The D compiler can avoid that trouble if somehow && || become a legacy or deprecated (but probably supported still) feature. It's also a matter of idioms and customs: D is a new language, it's not just an extension of the C language. So new D users usually accept the need to learn new customs and new idioms specific of the D language. D does many things differently from D (and even when it accepts C syntax, it's quite discouraged, like using "int a[];"). If D style guides, standard library, newsgroups, and books use 'and' and 'or' operators, new D programmers will use them. Thanks to bug 4077, a problem is now mitigated, if the original program with the thirdElementIsThree() function is compiled with dmd 2.049 plus warnings, the compiler shows: test.d(4): a.length >= 3 must be parenthesized when next to operator & test.d(4): a[2] == 3 must be parenthesized when next to operator & But fixing bug 4077 doesn't help bugs like: void main() { bool a, b; if (a & b) {} } The usage of 'and' and 'or' operators avoids this class of bugs too.
Comment #12 by smjg — 2010-09-20T18:04:33Z
(In reply to comment #11) > Some C++ programmers don't even know about 'and' and 'or' because > the C++ compilers do nothing to suggest, encourage or force the > usage of those more readable and less bug-prone operators. The D > compiler can avoid that trouble if somehow && || become a legacy or > deprecated (but probably supported still) feature. But because && and || are by far the most commonly used forms, and probably most modern languages with C-derived syntax are designed on this very basis, deprecating them would probably confuse the programmer by making D the odd one out. Moreover, a trend that has distinguished C and its derivatives from Pascal, Fortran, SQL et al is the tendency to make use of symbols, thereby keeping down the number of keywords in the language. D has continued this trend by doing away with the little-used and and or. OK, so D has is and in, but these aren't things for which other C-like languages have symbols (at least, I'm not sure if JS/PHP === is similar enough to count). > If D style guides, standard library, newsgroups, and books use > 'and' and 'or' operators, new D programmers will use them. And maybe get confused when they find that they don't behave in the same way as in Perl and PHP. Probably the obscurity of C's and/or has meant that the designers of Perl and PHP saw nothing wrong with changing the precedence. (Though why PHP's designer saw fit to change the associativity of ?: is a mystery I haven't solved.) > But fixing bug 4077 doesn't help bugs like: > > void main() { > bool a, b; > if (a & b) {} > } How's that a bug? When a and b are bools, they behave the same!
Comment #13 by bearophile_hugs — 2010-09-20T18:30:52Z
(In reply to comment #12) Stewart Gordon: > But because && and || are by far the most commonly used forms, and > probably most modern languages with C-derived syntax are designed on > this very basis, deprecating them would probably confuse the > programmer by making D the odd one out. I understand this. On the other hand Python and Delphi use 'or' and 'and' (Python is partially derived from C). I know some Python programmers interested in D. > D has continued this trend by doing away with the little-used and and or. And D uses a semicolon where Java uses 'implements' and 'extends'. > OK, so D has is and in, but these aren't things for which other > C-like languages have symbols In Python 'is' and 'in' have similar semantics. > And maybe get confused when they find that they don't behave in the > same way as in Perl and PHP. Probably this is a confusion for D newbies only, while what I have suggested is meant to help life of normal D programmers. > How's that a bug? When a and b are bools, they behave the same! OK. I close this enhancement request. If I will find other bug-prone situations I will reopen it. Thank you.
Comment #14 by braddr — 2010-09-20T18:37:57Z
It's not 'fixed'. It's either 'invalid' or 'wontfix' or 'notabug'. I'd prefer the latter, but since it's not available, going with 'wontfix'.
Comment #15 by shro8822 — 2010-09-20T22:15:25Z
(In reply to comment #11) > more > readable and less bug-prone operators. Franky I find the fact that && and || are not keywords make them *More* readable and as a result *Less* bug-prone. But there's no accounting for taste, yours or mine. One point to you, 1 point to me and Walter has trump.