www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A confusing expression?

reply bearophile <bearophileHUGS lycos.com> writes:
Time ago an automatic tool has said that in a line of C code similar to:
int r = x / y * z;

a division operator followed by a mult is confusing, and to add parentheses to
improve the code:
int r = (x / y) * z;


When values are integral the position of parentheses can change the value of
the expression:

void main() {
    int x = 10;
    int y = 3;
    int z = 5;
    assert(x / y * z == 15);
    assert((x / y) * z == 15);
    assert(x / (y * z) == 0);
}


Turning 'x / y * z' into a D syntax error (as done in bug 
http://d.puremagic.com/issues/show_bug.cgi?id=4077 ) looks excessive to me. A
warning seems enough, but Walter is not a lover of warnings (and sometimes I
agree, I'd like to turn three D warnings into errors). What do you think?

Bye,
bearophile
Aug 01 2010
next sibling parent reply mwarning <moritzwarning web.de> writes:
On Sun, 01 Aug 2010 19:22:42 -0400, bearophile wrote:

 Turning 'x / y * z' into a D syntax error (as done in bug 
 http://d.puremagic.com/issues/show_bug.cgi?id=4077 ) looks excessive to
 me. A warning seems enough, but Walter is not a lover of warnings (and
 sometimes I agree, I'd like to turn three D warnings into errors). What
 do you think?

Turning it into a syntax error sounds to be the right way to do to me. From a mathematical syntax pov, it's undefined behavior.
Aug 01 2010
parent bearophile <bearophileHUGS lycos.com> writes:
mwarning:
 Turning it into a syntax error sounds to be the right way to do to me.
 From a mathematical syntax pov, it's undefined behavior.

Thank you for your answer. You may be right, but this a hard sell :-) I'd like to know what others think about it. Eventually if the conditions are fit I can restart this thread in the main D newsgroup... Bye, bearophile
Aug 01 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Maybe we should have a special DMD flag to enable alternate warnings.

Maybe call it.. -walter ?

;P

bearophile Wrote:

 Time ago an automatic tool has said that in a line of C code similar to:
 int r = x / y * z;
 
 a division operator followed by a mult is confusing, and to add parentheses to
improve the code:
 int r = (x / y) * z;
 
 
 When values are integral the position of parentheses can change the value of
the expression:
 
 void main() {
     int x = 10;
     int y = 3;
     int z = 5;
     assert(x / y * z == 15);
     assert((x / y) * z == 15);
     assert(x / (y * z) == 0);
 }
 
 
 Turning 'x / y * z' into a D syntax error (as done in bug 
http://d.puremagic.com/issues/show_bug.cgi?id=4077 ) looks excessive to me. A
warning seems enough, but Walter is not a lover of warnings (and sometimes I
agree, I'd like to turn three D warnings into errors). What do you think?
 
 Bye,
 bearophile

Aug 01 2010
prev sibling next sibling parent reply Jason Spencer <spencer8 sbcglobal.net> writes:
I'm just trying to figure out what the error would be, exactly.  That a
programmer, knowing the language specification, obeyed it and wrote an
expression using the shortest syntax?

Rhetoric aside, the result is not unambiguous, it just requires that the
reader understand precedence.  That's an arguably good thing in any
case.

I could also make a similar argument that allowing operator overloading
might be confusing and so should be disallowed.  It's just an
unfortunate fact that programming requires some attention to detail.
Aug 02 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Jason Spencer:
 the result is not unambiguous, it just requires that the
 reader understand precedence.  That's an arguably good thing in any
 case.

You can say exactly the same thing regarding bug 4077. But we have chosen otherwise. Programming is done by people that do mistakes, so in some situations it's better to forbid some bug-prone syntax. In the case of * / the tool I have used asks for extra parenthesis. In this case I don't know what the best solution is yet. Bye, bearophile
Aug 02 2010
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 01 Aug 2010 19:22:42 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 Time ago an automatic tool has said that in a line of C code similar to:
 int r = x / y * z;

 a division operator followed by a mult is confusing, and to add  
 parentheses to improve the code:
 int r = (x / y) * z;


 When values are integral the position of parentheses can change the  
 value of the expression:

 void main() {
     int x = 10;
     int y = 3;
     int z = 5;
     assert(x / y * z == 15);
     assert((x / y) * z == 15);
     assert(x / (y * z) == 0);
 }

That has nothing to do with integral arguments. That has to do with precedence. assert(x / y * z == (x / y) * z); is going to pass no matter what the value/type of x, y, z. And given the values you have for x y z, the following statement is also true regardless of type: assert(x / y * z != x / (y * z));
 Turning 'x / y * z' into a D syntax error (as done in bug   
 http://d.puremagic.com/issues/show_bug.cgi?id=4077 ) looks excessive to  
 me. A warning seems enough, but Walter is not a lover of warnings (and  
 sometimes I agree, I'd like to turn three D warnings into errors). What  
 do you think?

No warning, no error. It's natural to assume that operations are performed from left to right. I don't find it confusing at all. -Steve
Aug 02 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 No warning, no error.  It's natural to assume that operations are  
 performed from left to right.  I don't find it confusing at all.

Thank you for your opinion Steven. I am now leaning toward your idea, because I think raising an error in this case it too much, and the other solutions I see are not good enough. So I presume this problem can be left to future D lint programs. Bye, bearophile
Aug 02 2010