www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is -1 > 7 ?

reply "michaelc37" <michaelc37 msn.com> writes:
forgive me if i'm doing something stupid, i'm extremely tired and 
trying to avoid drinking coffee.

void main()
{
	int[] arr = [0, 1, 2, 3, 4, 5, 6];

	//check 1
	if (-1 > arr.length)
		writefln("WTF -> %d is greater than %d ????", -1, arr.length);
	else
		writefln("GOOD -> %d is NOT greater than %d", -1, arr.length);
}

here is my output:
WTF -> -1 is greater than 7 ????
Aug 09 2013
next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
On Friday, 9 August 2013 at 15:11:42 UTC, michaelc37 wrote:
 forgive me if i'm doing something stupid, i'm extremely tired 
 and trying to avoid drinking coffee.

 void main()
 {
 	int[] arr = [0, 1, 2, 3, 4, 5, 6];

 	//check 1
 	if (-1 > arr.length)
 		writefln("WTF -> %d is greater than %d ????", -1, arr.length);
 	else
 		writefln("GOOD -> %d is NOT greater than %d", -1, arr.length);
 }

 here is my output:
 WTF -> -1 is greater than 7 ????
length is size_t, unsigned 64bit.
Aug 09 2013
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 9 August 2013 at 15:11:42 UTC, michaelc37 wrote:
 forgive me if i'm doing something stupid, i'm extremely tired 
 and trying to avoid drinking coffee.

 void main()
 {
 	int[] arr = [0, 1, 2, 3, 4, 5, 6];

 	//check 1
 	if (-1 > arr.length)
 		writefln("WTF -> %d is greater than %d ????", -1, arr.length);
 	else
 		writefln("GOOD -> %d is NOT greater than %d", -1, arr.length);
 }

 here is my output:
 WTF -> -1 is greater than 7 ????
And signed vs unsigned design issues pops up again! :) *summoning bearophile* On topic: arr.length has type size_t which is unsigned integer. -1 gets silently casted to unsigned, resulting in size_t.max value (0xFFF..) - which is obviously bigger than actual length. I believe it should be a compile-time error but, unfortunately, this is unlikely to happen.
Aug 09 2013
parent "michaelc37" <michaelc37 msn.com> writes:
On Friday, 9 August 2013 at 15:18:47 UTC, Dicebot wrote:
 On Friday, 9 August 2013 at 15:11:42 UTC, michaelc37 wrote:
 forgive me if i'm doing something stupid, i'm extremely tired 
 and trying to avoid drinking coffee.

 void main()
 {
 	int[] arr = [0, 1, 2, 3, 4, 5, 6];

 	//check 1
 	if (-1 > arr.length)
 		writefln("WTF -> %d is greater than %d ????", -1, 
 arr.length);
 	else
 		writefln("GOOD -> %d is NOT greater than %d", -1, 
 arr.length);
 }

 here is my output:
 WTF -> -1 is greater than 7 ????
And signed vs unsigned design issues pops up again! :) *summoning bearophile* On topic: arr.length has type size_t which is unsigned integer. -1 gets silently casted to unsigned, resulting in size_t.max value (0xFFF..) - which is obviously bigger than actual length. I believe it should be a compile-time error but, unfortunately, this is unlikely to happen.
Ahhh thanks for the explaination. if this was a compile time error, i would have saved precious time; I found strange behavior while writing some other related code, and I kept overlooking the condition thinking "it cant be that".
Aug 09 2013
prev sibling next sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
michaelc37 wrote:
 WTF -> -1 is greater than 7 ????
From the docs: It is an error to have one operand be signed and the other unsigned for a <, <=, > or >= expression. -manfred
Aug 09 2013
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Friday, 9 August 2013 at 15:28:10 UTC, Manfred Nowak wrote:
 michaelc37 wrote:
 WTF -> -1 is greater than 7 ????
From the docs: It is an error to have one operand be signed and the other unsigned for a <, <=, > or >= expression. -manfred
Interesting. I didn't know it was documented as being an outright error, I thought it was just "surprising"... I don't think Walter will ever accept to make it illegal though, breaks too much code. If this was a change he was OK with, I think we would have had it since day one, or at least, years ago. Related: std.algorithm.max *is* sign aware, and you can use code such as: if (a == max(a, b)) I have an pull request which creates the premise of functional "less"/"greater" operators, which are also sign aware: https://github.com/D-Programming-Language/phobos/pull/1365/files *If* it goes through, and *if* we make them public in std.functional, then it allows code such as: int a = -1; size_t b = 7; assert(a.less(b)); //Passes
Aug 09 2013
parent reply "Yota" <yotaxp thatGoogleMailThing.com> writes:
On Friday, 9 August 2013 at 17:35:18 UTC, monarch_dodra wrote:
 On Friday, 9 August 2013 at 15:28:10 UTC, Manfred Nowak wrote:
 michaelc37 wrote:
 WTF -> -1 is greater than 7 ????
From the docs: It is an error to have one operand be signed and the other unsigned for a <, <=, > or >= expression. -manfred
Interesting. I didn't know it was documented as being an outright error, I thought it was just "surprising"... I don't think Walter will ever accept to make it illegal though, breaks too much code. If this was a change he was OK with, I think we would have had it since day one, or at least, years ago.
I remember hearing somewhere that D is about enforcing users to write CORRECT code. I would really be disappointed with the language if this sort of gotcha weren't eliminated. If I look at this assert, I shouldn't be expecting it to pass. static assert(-1 > cast(size_t)7); IMHO, as long as this sort of comparison causes a compile-time error, as the docs say they should, this kind of breaking change is the of very good sort. The sort that reveals bugs in code. (Like when they changed the NULL macro to mean 'nullptr' instead of 0 in C++.) I couldn't imagine a programmer exploiting this intentionally, as it serves no purpose.
 Related: std.algorithm.max *is* sign aware, and you can use 
 code such as:
 if (a == max(a, b))

 I have an pull request which creates the premise of functional 
 "less"/"greater" operators, which are also sign aware:
 https://github.com/D-Programming-Language/phobos/pull/1365/files

 *If* it goes through, and *if* we make them public in 
 std.functional, then it allows code such as:
 int a = -1;
 size_t b = 7;
 assert(a.less(b)); //Passes
That is pretty cool, but unless the comparison operators actually use that code, (which they probably won't, since it's not a library thing?) it will only provide a workaround to the problem.
Aug 11 2013
parent reply "Andre Artus" <andre.artus gmail.com> writes:
On Sunday, 11 August 2013 at 17:01:46 UTC, Yota wrote:
 On Friday, 9 August 2013 at 17:35:18 UTC, monarch_dodra wrote:
 On Friday, 9 August 2013 at 15:28:10 UTC, Manfred Nowak wrote:
 michaelc37 wrote:
 WTF -> -1 is greater than 7 ????
From the docs: It is an error to have one operand be signed and the other unsigned for a <, <=, > or >= expression. -manfred
Interesting. I didn't know it was documented as being an outright error, I thought it was just "surprising"... I don't think Walter will ever accept to make it illegal though, breaks too much code. If this was a change he was OK with, I think we would have had it since day one, or at least, years ago.
I remember hearing somewhere that D is about enforcing users to write CORRECT code. I would really be disappointed with the language if this sort of gotcha weren't eliminated. If I look at this assert, I shouldn't be expecting it to pass. static assert(-1 > cast(size_t)7); IMHO, as long as this sort of comparison causes a compile-time error, as the docs say they should, this kind of breaking change is the of very good sort. The sort that reveals bugs in code. (Like when they changed the NULL macro to mean 'nullptr' instead of 0 in C++.) I couldn't imagine a programmer exploiting this intentionally, as it serves no purpose.
I agree, breaking changes that expose bugs in your code are the good kind. The time spent fixing compile time errors is more than compensated for by the time saved not having to hunt down those bugs. Having worked with languages where reference types are non-nullable by default I wish more languages did the same. More often than not when a null makes it past the public interface to an app or library then it is an error. So much code can be simplified when the compiler looks a Null square in the mug and declares, "thou shalt not pass!" I dislike implicit conversions at the best of times, but implicit conversions that change sign or drop bits is a design mistake that needs to be fixed. I break out in convulsions at the sight of them. D has many great features [1] that help eliminate common errors, but there still seems to be a few rough edges. 1.I recently learned about D's ability to write integers with underscores, this is a great feature (if a bit tricky to generate a lexer for [without handwritten code]). I think that, 0b0010_1001__1101_1001__1101_1100__1101_100 is so much easier to grok, and to see a that a digit may be missing from the end, effectively a right shift, than the alternative 0b0010100111011001110111001101100 Only trip up is that 0b__1 == 0b1__ == 0b_1_ == 1 (for understandable reasons, but something to keep an eye out for)
 Related: std.algorithm.max *is* sign aware, and you can use 
 code such as:
 if (a == max(a, b))

 I have an pull request which creates the premise of functional 
 "less"/"greater" operators, which are also sign aware:
 https://github.com/D-Programming-Language/phobos/pull/1365/files

 *If* it goes through, and *if* we make them public in 
 std.functional, then it allows code such as:
 int a = -1;
 size_t b = 7;
 assert(a.less(b)); //Passes
That is pretty cool, but unless the comparison operators actually use that code, (which they probably won't, since it's not a library thing?) it will only provide a workaround to the problem.
Aug 14 2013
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
On 8/14/13 2:26 PM, Andre Artus wrote:
 On Sunday, 11 August 2013 at 17:01:46 UTC, Yota wrote:
 On Friday, 9 August 2013 at 17:35:18 UTC, monarch_dodra wrote:
 On Friday, 9 August 2013 at 15:28:10 UTC, Manfred Nowak wrote:
 michaelc37 wrote:
 WTF -> -1 is greater than 7 ????
From the docs: It is an error to have one operand be signed and the other unsigned for a <, <=, > or >= expression. -manfred
Interesting. I didn't know it was documented as being an outright error, I thought it was just "surprising"... I don't think Walter will ever accept to make it illegal though, breaks too much code. If this was a change he was OK with, I think we would have had it since day one, or at least, years ago.
I remember hearing somewhere that D is about enforcing users to write CORRECT code. I would really be disappointed with the language if this sort of gotcha weren't eliminated. If I look at this assert, I shouldn't be expecting it to pass. static assert(-1 > cast(size_t)7); IMHO, as long as this sort of comparison causes a compile-time error, as the docs say they should, this kind of breaking change is the of very good sort. The sort that reveals bugs in code. (Like when they changed the NULL macro to mean 'nullptr' instead of 0 in C++.) I couldn't imagine a programmer exploiting this intentionally, as it serves no purpose.
I agree, breaking changes that expose bugs in your code are the good kind. The time spent fixing compile time errors is more than compensated for by the time saved not having to hunt down those bugs. Having worked with languages where reference types are non-nullable by default I wish more languages did the same.
Which are those languages? I'm interested.
Aug 14 2013
parent "Andre Artus" <andre.artus gmail.com> writes:
On Wednesday, 14 August 2013 at 18:08:56 UTC, Ary Borenszweig 
wrote:
 On 8/14/13 2:26 PM, Andre Artus wrote:
 On Sunday, 11 August 2013 at 17:01:46 UTC, Yota wrote:
 On Friday, 9 August 2013 at 17:35:18 UTC, monarch_dodra wrote:
 On Friday, 9 August 2013 at 15:28:10 UTC, Manfred Nowak 
 wrote:
 michaelc37 wrote:
 WTF -> -1 is greater than 7 ????
From the docs: It is an error to have one operand be signed and the other unsigned for a <, <=, > or >= expression. -manfred
Interesting. I didn't know it was documented as being an outright error, I thought it was just "surprising"... I don't think Walter will ever accept to make it illegal though, breaks too much code. If this was a change he was OK with, I think we would have had it since day one, or at least, years ago.
I remember hearing somewhere that D is about enforcing users to write CORRECT code. I would really be disappointed with the language if this sort of gotcha weren't eliminated. If I look at this assert, I shouldn't be expecting it to pass. static assert(-1 > cast(size_t)7); IMHO, as long as this sort of comparison causes a compile-time error, as the docs say they should, this kind of breaking change is the of very good sort. The sort that reveals bugs in code. (Like when they changed the NULL macro to mean 'nullptr' instead of 0 in C++.) I couldn't imagine a programmer exploiting this intentionally, as it serves no purpose.
I agree, breaking changes that expose bugs in your code are the good kind. The time spent fixing compile time errors is more than compensated for by the time saved not having to hunt down those bugs. Having worked with languages where reference types are non-nullable by default I wish more languages did the same.
Which are those languages? I'm interested.
Haskell, there are functions called "null", but they are [normally] equivalent to "isEmpty". Tri-values and other cases for null covered by "Maybe"/"Either". F#, has null to interface with other .NET languages, but only used on the boundaries. Most other cases for null covered with "option". Spec#, when compiling with the "/nn" switch. It's a research clone of C# with Eiffel-like features (i.e. contracts). You can cast from a nullable type to a not-null type in which case the compiler inserts a run-time check. There is also a strict type annotation "!" forcing not-null semantics even when compiling without "/nn". Unfortunately it's not being actively maintained (AFAIK) and has fallen behind on the latest C# features. http://specsharp.codeplex.com/ I have not used Eiffel, something about the syntax does not appeal to me [1], but I believe it has the concept of "void safety" which you can read about here: http://docs.eiffel.com/book/papers/void-safety-how-eiffel-removes-null-pointer-dereferencing 1. I'm not knocking Eiffel, it has pioneered or promoted many important innovations in OOP. My view on the syntax is like my taste in ice-cream: merely a personal opinion.
Aug 14 2013
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/9/13, Manfred Nowak <svv1999 hotmail.com> wrote:
 michaelc37 wrote:
 WTF -> -1 is greater than 7 ????
From the docs: It is an error to have one operand be signed and the other unsigned for a <, <=, > or >= expression. -manfred
Chances are generic code would break, so maybe that part of the docs should be removed. I've already tried implementing something related to comparisons like this but it did end up breaking code: https://github.com/D-Programming-Language/dmd/pull/1337
Aug 09 2013
prev sibling next sibling parent "michaelc37" <michaelc37 msn.com> writes:
http://d.puremagic.com/issues/show_bug.cgi?id=259
https://github.com/D-Programming-Language/dmd/pull/1913

Looks like there has a pending fix for 4 months.
Aug 09 2013
prev sibling parent luka8088 <luka8088 owave.net> writes:
On 9.8.2013. 17:11, michaelc37 wrote:
 forgive me if i'm doing something stupid, i'm extremely tired and trying
 to avoid drinking coffee.

 void main()
 {
 int[] arr = [0, 1, 2, 3, 4, 5, 6];

 //check 1
 if (-1 > arr.length)
 writefln("WTF -> %d is greater than %d ????", -1, arr.length);
 else
 writefln("GOOD -> %d is NOT greater than %d", -1, arr.length);
 }

 here is my output:
 WTF -> -1 is greater than 7 ????
http://forum.dlang.org/thread/kn3f9v$25pd$1 digitalmars.com
Aug 14 2013