digitalmars.D.learn - Bug? 0 is less than -10
- tcak (15/15) Oct 06 2015 Maybe I am just too stressed out to see the problem.
- Adam D. Ruppe (7/11) Oct 06 2015 size_t is unsigned, so the -10 is cast to unsigned too for the
- Laeeth Isharc (3/14) Oct 06 2015 could we have ssize_t defined in phobos somewhere so your code
- Steven Schveighoffer (3/5) Oct 06 2015 ptrdiff_t
- Laeeth Isharc (9/15) Oct 06 2015 It seems unnatural to use such a name when the variable has
- Andrea Fontana (3/20) Oct 07 2015 IMO it seems unnatural to use size_t with a signed/negative value
- Laeeth Isharc (10/33) Oct 07 2015 Indeed. But you end up with an inferred size_t in a foreach and
- Steven Schveighoffer (5/18) Oct 08 2015 ptrdiff_t is in the C spec, ssize_t is not. No reason to name all the
- Laeeth Isharc (11/38) Oct 08 2015 Whatever - it's not that important to me. D isn't C, and has
- anonymous (3/18) Oct 06 2015 dec is a size_t. size_t is unsigned. -10 is cast to unsigned for
- Meta (5/20) Oct 06 2015 If you need to mix signed and unsigned values but want to avoid
- Marc =?UTF-8?B?U2Now7x0eg==?= (5/20) Oct 07 2015 Lionello Lunesu posted a PR that should fix this:
- Dominikus Dittes Scherkl (25/29) Oct 08 2015 Meanwhile I have even improved my solution posted to fix bug #259
- Ozan (4/18) Oct 09 2015 ...
Maybe I am just too stressed out to see the problem. [code] import std.stdio; void main(){ size_t dec = 0; writeln( dec, " ", (dec <= -10), " ", (dec >= 10), " ", ((dec <= -10) || (dec >= 10)) ); } [/code] [output] 0 true false true [/output] How is it generating "true" for (dec <= -10) ? Is there a special casting or something? DMD 2.068.2, Ubuntu 64-bit
Oct 06 2015
On Tuesday, 6 October 2015 at 14:46:56 UTC, tcak wrote:void main(){ size_t dec = 0;How is it generating "true" for (dec <= -10) ? Is there a special casting or something?size_t is unsigned, so the -10 is cast to unsigned too for the comparison which yields some huge number. Comparing signed to unsigned is almost always a mistake... but one D inherited from C. This is a reason why I prefer to use int instead of size_t where I can but that might require casts and truncation too.
Oct 06 2015
On Tuesday, 6 October 2015 at 14:55:23 UTC, Adam D. Ruppe wrote:On Tuesday, 6 October 2015 at 14:46:56 UTC, tcak wrote:could we have ssize_t defined in phobos somewhere so your code ends up being portable ;) (It's trivial to do, obviously).void main(){ size_t dec = 0;How is it generating "true" for (dec <= -10) ? Is there a special casting or something?size_t is unsigned, so the -10 is cast to unsigned too for the comparison which yields some huge number. Comparing signed to unsigned is almost always a mistake... but one D inherited from C. This is a reason why I prefer to use int instead of size_t where I can but that might require casts and truncation too.
Oct 06 2015
On 10/6/15 7:21 PM, Laeeth Isharc wrote:could we have ssize_t defined in phobos somewhere so your code ends up being portable ;) (It's trivial to do, obviously).ptrdiff_t -Steve
Oct 06 2015
On Wednesday, 7 October 2015 at 02:53:32 UTC, Steven Schveighoffer wrote:On 10/6/15 7:21 PM, Laeeth Isharc wrote:It seems unnatural to use such a name when the variable has nothing to do with pointers - it doesn't contribute to the readability. Yes, it's trivial, but small things cumulatively matter. Adam tends to use int and when that gets mixed up with an auto size_t (eg via length) then his code doesn't compile on 64 bit. And if it happens with his code, you can imagine this isn't a problem that inexperienced users never encounter.could we have ssize_t defined in phobos somewhere so your code ends up being portable ;) (It's trivial to do, obviously).ptrdiff_t -Steve
Oct 06 2015
On Wednesday, 7 October 2015 at 05:27:12 UTC, Laeeth Isharc wrote:On Wednesday, 7 October 2015 at 02:53:32 UTC, Steven Schveighoffer wrote:IMO it seems unnatural to use size_t with a signed/negative value too.On 10/6/15 7:21 PM, Laeeth Isharc wrote:It seems unnatural to use such a name when the variable has nothing to do with pointers - it doesn't contribute to the readability. Yes, it's trivial, but small things cumulatively matter. Adam tends to use int and when that gets mixed up with an auto size_t (eg via length) then his code doesn't compile on 64 bit. And if it happens with his code, you can imagine this isn't a problem that inexperienced users never encounter.could we have ssize_t defined in phobos somewhere so your code ends up being portable ;) (It's trivial to do, obviously).ptrdiff_t -Steve
Oct 07 2015
On Wednesday, 7 October 2015 at 07:38:44 UTC, Andrea Fontana wrote:On Wednesday, 7 October 2015 at 05:27:12 UTC, Laeeth Isharc wrote:Indeed. But you end up with an inferred size_t in a foreach and using length with auto, so it makes sense to have something nicer that you can specify that won't make your code look strange. Doesn't bother me since I define ssize_t, but it might make D easier to read for others. When you see ptrdiff_t with no pointer in sight it's not very clear unless you are familiar with C idioms (and I never remember seeing this back when I learnt C - some modern thing).On Wednesday, 7 October 2015 at 02:53:32 UTC, Steven Schveighoffer wrote:IMO it seems unnatural to use size_t with a signed/negative value too.On 10/6/15 7:21 PM, Laeeth Isharc wrote:It seems unnatural to use such a name when the variable has nothing to do with pointers - it doesn't contribute to the readability. Yes, it's trivial, but small things cumulatively matter. Adam tends to use int and when that gets mixed up with an auto size_t (eg via length) then his code doesn't compile on 64 bit. And if it happens with his code, you can imagine this isn't a problem that inexperienced users never encounter.could we have ssize_t defined in phobos somewhere so your code ends up being portable ;) (It's trivial to do, obviously).ptrdiff_t -Steve
Oct 07 2015
On 10/7/15 1:27 AM, Laeeth Isharc wrote:On Wednesday, 7 October 2015 at 02:53:32 UTC, Steven Schveighoffer wrote:ptrdiff_t is in the C spec, ssize_t is not. No reason to name all the types of snow here. A machine-word-sized signed integer is ptrdiff_t. -SteveOn 10/6/15 7:21 PM, Laeeth Isharc wrote:It seems unnatural to use such a name when the variable has nothing to do with pointers - it doesn't contribute to the readability. Yes, it's trivial, but small things cumulatively matter. Adam tends to use int and when that gets mixed up with an auto size_t (eg via length) then his code doesn't compile on 64 bit. And if it happens with his code, you can imagine this isn't a problem that inexperienced users never encounter.could we have ssize_t defined in phobos somewhere so your code ends up being portable ;) (It's trivial to do, obviously).ptrdiff_t
Oct 08 2015
On Thursday, 8 October 2015 at 13:32:17 UTC, Steven Schveighoffer wrote:On 10/7/15 1:27 AM, Laeeth Isharc wrote:Whatever - it's not that important to me. D isn't C, and has learnt from C's mistakes and infelicities. I love the beauty of C, but I'm glad I don't need to do my work in it. One reason why D is under appreciated is that these seemingly small differences make a big difference in practice, even if in theory they shouldn't. Initially I was quite offended by no loop aliasing. Until I saw how much time it saved me in avoiding silly mistakes. But really there are better things to worry about at the moment. Laeeth.On Wednesday, 7 October 2015 at 02:53:32 UTC, Steven Schveighoffer wrote:ptrdiff_t is in the C spec, ssize_t is not. No reason to name all the types of snow here. A machine-word-sized signed integer is ptrdiff_t. -SteveOn 10/6/15 7:21 PM, Laeeth Isharc wrote:It seems unnatural to use such a name when the variable has nothing to do with pointers - it doesn't contribute to the readability. Yes, it's trivial, but small things cumulatively matter. Adam tends to use int and when that gets mixed up with an auto size_t (eg via length) then his code doesn't compile on 64 bit. And if it happens with his code, you can imagine this isn't a problem that inexperienced users never encounter.could we have ssize_t defined in phobos somewhere so your code ends up being portable ;) (It's trivial to do, obviously).ptrdiff_t
Oct 08 2015
On Tuesday, 6 October 2015 at 14:46:56 UTC, tcak wrote:Maybe I am just too stressed out to see the problem. [code] import std.stdio; void main(){ size_t dec = 0; writeln( dec, " ", (dec <= -10), " ", (dec >= 10), " ", ((dec <= -10) || (dec >= 10)) ); } [/code] [output] 0 true false true [/output] How is it generating "true" for (dec <= -10) ? Is there a special casting or something? DMD 2.068.2, Ubuntu 64-bitdec is a size_t. size_t is unsigned. -10 is cast to unsigned for the comparison, resulting in some huge value.
Oct 06 2015
On Tuesday, 6 October 2015 at 14:46:56 UTC, tcak wrote:Maybe I am just too stressed out to see the problem. [code] import std.stdio; void main(){ size_t dec = 0; writeln( dec, " ", (dec <= -10), " ", (dec >= 10), " ", ((dec <= -10) || (dec >= 10)) ); } [/code] [output] 0 true false true [/output] How is it generating "true" for (dec <= -10) ? Is there a special casting or something? DMD 2.068.2, Ubuntu 64-bitIf you need to mix signed and unsigned values but want to avoid this issue, you an use the comparison functions from std.functional.
Oct 06 2015
On Tuesday, 6 October 2015 at 14:46:56 UTC, tcak wrote:Maybe I am just too stressed out to see the problem. [code] import std.stdio; void main(){ size_t dec = 0; writeln( dec, " ", (dec <= -10), " ", (dec >= 10), " ", ((dec <= -10) || (dec >= 10)) ); } [/code] [output] 0 true false true [/output] How is it generating "true" for (dec <= -10) ? Is there a special casting or something? DMD 2.068.2, Ubuntu 64-bitLionello Lunesu posted a PR that should fix this: https://github.com/D-Programming-Language/dmd/pull/1913 See also the discussion in the linked bug report. Unfortunately it seems it's been forgotten since then...
Oct 07 2015
On Wednesday, 7 October 2015 at 16:25:02 UTC, Marc Schütz wrote:Lionello Lunesu posted a PR that should fix this: https://github.com/D-Programming-Language/dmd/pull/1913 See also the discussion in the linked bug report. Unfortunately it seems it's been forgotten since then...to use less casts: int opCmp(T, U)(const(T) a, const(U) b) pure safe nogc nothrow if(isIntegral!T && isIntegral!U && !is(Unqual!T == Unqual!U)) { static if(isSigned!T && isUnsigned!U && T.sizeof <= U.sizeof) { return (a < 0) ? -1 : opCmp(cast(U)a, b); } else static if(isUnsigned!T && isSigned!U && T.sizeof >= U.sizeof) { return (b < 0) ? 1 : opCmp(a, cast(T)b); } else // both signed or both unsigned or the unsigned type is smaller { // do what the compiler always did so far: alias C = CommonType!(T, U); // use the larger of the both return opCmp(cast(C)a, cast(C)b); } } And on comparison with number literals everything will be optimized away, so no execution timer overhead at all!
Oct 08 2015
On Thursday, 8 October 2015 at 09:01:32 UTC, Dominikus Dittes Scherkl wrote:On Wednesday, 7 October 2015 at 16:25:02 UTC, Marc Schütz wrote:...Lionello Lunesu posted a PR that should fix this: https://github.com/D-Programming-Language/dmd/pull/1913 See also the discussion in the linked bug report. Unfortunately it seems it's been forgotten since then...Meanwhile I have even improved my solution posted to fix bug int opCmp(T, U)(const(T) a, const(U) b) pure safe nogc nothrow if(isIntegral!T && isIntegral!U && !is(Unqual!T == Unqual!U)) { static if(isSigned!T && isUnsigned!U && T.sizeof <= U.sizeof)And on comparison with number literals everything will be optimized away, so no execution timer overhead at all!I like your solution! +1
Oct 09 2015