www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3847] New: To avoid a C code bug

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847

           Summary: To avoid a C code bug
           Product: D
           Version: 2.040
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 23 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


Ellery Newcomer <ellery-newcomer utulsa.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ellery-newcomer utulsa.edu



18:39:12 PST ---

 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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 23 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


BCS <shro8822 vandals.uidaho.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |shro8822 vandals.uidaho.edu



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

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 23 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com




 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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 27 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847




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);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com



11:00:26 PDT ---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


Adam D. Ruppe <destructionator gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |destructionator gmail.com



11:26:55 PDT ---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847




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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


Brad Roberts <braddr puremagic.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |braddr puremagic.com



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

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


Ary Borenszweig <ary esperanto.org.ar> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ary esperanto.org.ar



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

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847




21:14:14 PDT ---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 03 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847





 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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847





 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! -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED




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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847


Brad Roberts <braddr puremagic.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|FIXED                       |WONTFIX



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

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 20 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3847




---

 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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2010