[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Iain Buclaw changed: What|Removed |Added Priority|P2 |P4 --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #73 from thomas.bock...@gmail.com --- (In reply to Stewart Gordon from comment #72) > I don't understand. How can code that the spec explicitly forbids possibly > be correct? Normal programmers, who are not language lawyers, generally consider code to be correct if it reliably does what it is intended to do, in the way it is intended to do it. They do not know or care what the language spec says, and they assume the compiler can be trusted to enforce such simple rules as "mixed signed-unsigned comparisons are forbidden", if necessary. And, this is a perfectly rational approach, since both the compiler and the spec are complex, change over time, and sometimes contradict each other. Where there is a conflict, a programmer must satisfy the compiler in order to get work done, while the spec is important only in theory. Regardless of what the spec says, the de-facto semantics of the D language are that mixed signed-unsigned integer comparisons in D use integer promotion, like other mixed operations. That can certainly be changed, but the compiler needs to point out code that needs to be updated for the new semantics via warnings, deprecations, or errors. People need to be able to write code and then move on with their lives, and must not be forced to memorize the language spec and manually review all of the code they have ever written in D every time a new version of the compiler or spec comes out, to avoid silent breakage. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #72 from Stewart Gordon --- (In reply to thomas.bockman from comment #71) > The real problem is that the current strange behaviour of mixed comparisons > is occasionally deliberately used in correct code. D must not be updated in > a way that silently breaks all that pre-existing correct code. Hence, a > warning (or at least, a *long* deprecation period) is the only good option > for D2. I don't understand. How can code that the spec explicitly forbids possibly be correct? --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #71 from thomas.bock...@gmail.com --- (In reply to Manuel König from comment #69) > Not sure how to deal with the slower comparisons like long-unsigned > that have no direct assembly comparison instruction, maybe just > produce an error message. Speed is not the issue. The performance cost of a correct signed-unsigned comparison is almost nothing (less than the cost of a single branch mispredict, I believe), and in those very rare cases where the tiny speed boost of doing the comparison incorrectly is really worth it, it is trivial to cast one of the operands to the type of the other. The real problem is that the current strange behaviour of mixed comparisons is occasionally deliberately used in correct code. D must not be updated in a way that silently breaks all that pre-existing correct code. Hence, a warning (or at least, a *long* deprecation period) is the only good option for D2. Introducing such a warning without drowning people in false positives is surprisingly complicated, and is currently stalled waiting for a chain of compiler changes to be completed: https://github.com/dlang/dmd/pull/12311 https://github.com/dlang/dmd/pull/5229 https://github.com/dlang/dmd/pull/1913 --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #70 from Basile-z --- The promotion trick works unless both operand are 64 bits (and considering that cent/ucent are not a thing yet) but that would be a progress. For long cmp ulong a warning could be emitted. This topic should make its come back on the news group. Even if the current behavior is layered on C semantics that does not mean that it could not change. Following C is not a sacrosant rule. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Manuel König changed: What|Removed |Added CC||manuel...@gmx.net --- Comment #69 from Manuel König --- I hit this 15 years old bug again, and now feel very insecure about the correctness of all integer comparisons in all my code. At least a warning about signed-unsigned comparison would be great, doing the mathematically correct fast & safe integer promotions would be even better. Not sure how to deal with the slower comparisons like long-unsigned that have no direct assembly comparison instruction, maybe just produce an error message. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Walter Bright changed: What|Removed |Added CC||bugzi...@digitalmars.com Severity|critical|enhancement --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Issue 259 depends on issue 9960, which changed state. Issue 9960 Summary: Show warnings/deprecations during template instantiation https://issues.dlang.org/show_bug.cgi?id=9960 What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #68 from hst...@quickfur.ath.cx --- Whoa. This is approaching 12 years now, and even has a preapproved pull. When will the fix actually get merged?! --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 hst...@quickfur.ath.cx changed: What|Removed |Added CC||hst...@quickfur.ath.cx --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Nick Treleavenchanged: What|Removed |Added See Also||https://issues.dlang.org/sh ||ow_bug.cgi?id=12919 --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #67 from Andrei Alexandrescu--- (In reply to thomas.bockman from comment #66) > Oops! That's the wrong DMD bug. This is the one I > actually meant: > https://issues.dlang.org/show_bug.cgi?id=14835 That makes sense. Thanks, and for the update as well. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #66 from thomas.bock...@gmail.com --- Oops! That's the wrong DMD bug. This is the one I actually meant: https://issues.dlang.org/show_bug.cgi?id=14835 --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 thomas.bock...@gmail.com changed: What|Removed |Added CC||thomas.bock...@gmail.com --- Comment #65 from thomas.bock...@gmail.com --- (In reply to Andrei Alexandrescu from comment #64) > We should be fine with a slight loss in efficiency in > mixed sign compare. The previously agreed upon solution was to default to warning about each signed/unsigned comparison, but omit the warning if VRP could prove it to be safe. There is no loss of run-time efficiency that way, but some code will break and require an explicit cast to fix. Are you suggesting that we should just insert an extra comparison to zero as needed, instead? I'd support that, but I don't know how others (including Walter Bright) would feel about it. The real performance impact should be immeasurably small in nearly all cases (especially with the VRP upgrades discussed below). > What active PRs are open at this time? My DMD #5229 is a continuation of Lionello's work toward improving VRP sufficiently to minimize code breakage: https://github.com/dlang/dmd/pull/5229 However, it's stuck pending a resolution to another DMD bug: https://issues.dlang.org/show_bug.cgi?id=15585 If #5229 ever gets pulled, one more tricky VRP- related follow-up is required to make the compiler smart enough. After that, actually fixing this bug is trivial: I've had that patch ready to go for about a year now, but can't submit it until the VRP stuff is straightened out because it causes too much breakage. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #64 from Andrei Alexandrescu--- Time to finalize this. We should be fine with a slight loss in efficiency in mixed sign compare. What active PRs are open at this time? --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #63 from Dominikus Dittes Scherkl--- (In reply to Dominikus Dittes Scherkl from comment #58) > So why don't we change to something that simply always works? I have meanwhile improved my solution to something more straight forward, with less superfluous casting, and now that the frontend is written in D, it should be no problem to integrate it in the compiler: 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 // do interger propagation as ever: return opCmp(cast(CommonType!(T, U))a, cast(CommonType!(T, U))b); } --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Jon Degenhardtchanged: What|Removed |Added CC||jrdemail2000-dl...@yahoo.co ||m --- Comment #62 from Jon Degenhardt --- Hit this in my code. My bug, but would have been useful if the compiler had informed me there was a signed vs unsigned comparison. Here's the reduced form of what was happening in my code: void main() { int i = -1; size_t j = 0; assert(i < j); } This code compiles, and the assert fails. Except that I didn't have the assert, just the test. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Sobirari Muhomorichanged: What|Removed |Added Keywords||industry --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Andrei Alexandrescu and...@erdani.com changed: What|Removed |Added Target Milestone|2.059 |--- Version|D1 D2 |D2 --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 naptime naptimeentertainm...@gmail.com changed: What|Removed |Added CC||naptimeentertainment@gmail. ||com --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #59 from Lionello Lunesu lio+bugzi...@lunesu.com --- It's currently using the C integer promotion rules, which are consistent (they're rules after all) but far from simple. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Dominikus Dittes Scherkl domini...@scherkl.de changed: What|Removed |Added CC||domini...@scherkl.de --- Comment #58 from Dominikus Dittes Scherkl domini...@scherkl.de --- The problem is still there, and the behaviour is completely inconsistent, so braking any code isn't a problem I think because I cannot imagine that anybody really relies on the strange behaviour: unittest { byte a = -3; ubyte b = 2; short c = -3; ushort d = 2; inte = -3; uint f = 2; long g = -3; ulong h = 2; assert(a b); assert(c d); assert(e f); // fails!! assert(g h); // fails!! assert(a h); // fails!! assert(b g); assert(d e); } So why don't we change to something that simply always works? int opCmp(T, U)(const(T) a, const(U) b) pure @safe @nogc nothrow if(is(Unqual!T == Unqual!U) || isFloatingPoint!T || isFloatingPoint!U) { // Should be buildin. Naive implementation: return a = b ? a != b ? -1 : 0 : 1; } /// Returns negative value if a b, 0 if they are equal or positive value if a b. /// This will always yield a correct result, no matter which integral types are compared. /// It uses one extra comparison operation if and only if /// one type is signed and the other unsigned but has bigger max. 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(T.sizeof == U.sizeof) alias C = Unsigned!T; else alias C = CommonType!(T, U); // this will be the larger type static if(isSigned!T isUnsigned!U T.sizeof = U.sizeof) { return (a 0) ? -1 : opCmp(cast(Unsigned!C)a, cast(C)b); } else static if(isUnsigned!T isSigned!U T.sizeof = U.sizeof) { return (b 0) ? 1 : opCmp(cast(C)a, cast(Unsigned!C)b); } else { // both signed or both unsigned or the unsigned type is smaller // and can therefore be safely cast to the signed type return opCmp(cast(C)a, cast(C)b); } } --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #61 from Stewart Gordon s...@iname.com --- (In reply to Dominikus Dittes Scherkl from comment #58) The problem is still there, and the behaviour is completely inconsistent, so braking any code isn't a problem I think because I cannot imagine that anybody really relies on the strange behaviour: Exactly, because it won't break any code. It will cause code that is already broken to correctly error. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #60 from Dominikus Dittes Scherkl domini...@scherkl.de --- (In reply to Lionello Lunesu from comment #59) It's currently using the C integer promotion rules, which are consistent (they're rules after all) but far from simple. Ah, ok. I see why ab and cd work - they are all promoted to int. But never the less: who would be affected by changing the behaviour for int and long? Is really anybody relying on that? And sure that was not a bug from the beginning? I don't think that we really should keep bugs just to be consistend with C. -- this is a case where a compiler warning is good: Comparing signed with unsigned values. This works in D but may be a performance issue and behaves different from C. Is this intended? (of course works only after the fix :-) --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #57 from Lionello Lunesu lio+bugzi...@lunesu.com --- (In reply to Andrei Alexandrescu from comment #56) What's left to do about this? I need to finish some of the static code analysis that I have been adding so we get less false positives. It's the false positives that will turn Walter (and others) off and prevent merging it in. --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #56 from Andrei Alexandrescu and...@erdani.com --- What's left to do about this? --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 Marc Schütz schue...@gmx.net changed: What|Removed |Added CC||schue...@gmx.net --
[Issue 259] Comparing signed to unsigned does not generate an error
https://issues.dlang.org/show_bug.cgi?id=259 --- Comment #55 from github-bugzi...@puremagic.com --- Commit pushed to master at https://github.com/D-Programming-Language/druntime https://github.com/D-Programming-Language/druntime/commit/8890678458e775e93ade1de307a417b06032ee0f Merge pull request #799 from lionello/bug259 Fixed some signed/unsigned warnings in druntime --
[Issue 259] Comparing signed to unsigned does not generate an error
https://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #54 from bearophile_h...@eml.cc 2013-12-07 06:48:38 PST --- If an immutable int x is inside the if branch that asserts it to be not negative, the assignments and comparisons with an uint should not give warnings: uint z; void main(string[] args) { immutable int x = args.length - 3; if (x = 0) { uint y = x; // give no errors here if (x z) {} // give no warning here. } } -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #52 from Lionello Lunesu lio+bugzi...@lunesu.com 2013-09-07 12:12:57 PDT --- Also submitted fixes to druntime: https://github.com/D-Programming-Language/druntime/pull/601 (Note: check the pull requests for the latest info) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Nick Treleaven ntrel-pub...@yahoo.co.uk changed: What|Removed |Added CC||ntrel-pub...@yahoo.co.uk --- Comment #51 from Nick Treleaven ntrel-pub...@yahoo.co.uk 2013-08-20 03:11:43 PDT --- (In reply to comment #47) https://github.com/D-Programming-Language/dmd/pull/1889 Update: that was split into two, see: https://github.com/D-Programming-Language/dmd/pull/1913 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #50 from Lionello Lunesu lio+bugzi...@lunesu.com 2013-05-03 14:20:12 PDT --- I've discovered one additional case, 1b. If both types can be cast to the bigger signed type, the cast is safe -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #49 from Lionello Lunesu lio+bugzi...@lunesu.com 2013-04-12 22:01:28 PDT --- We should probably consider making this a warning or deprecation, instead of an error. The silent failures within templates make it very hard to fix code. Warnings and errors during template instantiations are suppressed and the final errors instantiating template doesn't say why (not even with -v; this is probably worth a filing a separate bug for.) I'm having to add a printf to expression.c to see those occurrences, \util\dmd2\src\phobos\std\format.d(1216) \util\dmd2\src\phobos\std\format.d(1224) \util\dmd2\src\phobos\std\format.d(1395) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #47 from Lionello Lunesu lio+bugzi...@lunesu.com 2013-04-11 19:24:53 PDT --- https://github.com/D-Programming-Language/dmd/pull/1889 There are many things silently(!) breaking, though, as some templates are not being chosen because of internal comparison errors. For example, FormatSpec.width and FormatSpec.precision are ints but often compared against array lengths (for padding and such). TBH, using negative width and precision to mean argument index is a hack and we'd be better off changing them to uint and use a flag for the argument index case. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #48 from Lionello Lunesu lio+bugzi...@lunesu.com 2013-04-11 19:42:37 PDT --- // For the record: my test cases. Will add/fix existing unittests as well. import std.traits; int i; uint ui; long l; ulong ul; // 0. same-signed-ness static assert(__traits(compiles, uiul)); static assert(__traits(compiles, ului)); static assert(__traits(compiles, il)); static assert(__traits(compiles, li)); static assert(__traits(compiles, 12)); static assert(!(12)); static assert(__traits(compiles, 21)); static assert(21); // 1. sizeof(signed) sizeof(unsigned) static assert(__traits(compiles, lui)); static assert(__traits(compiles, uil)); static assert(__traits(compiles, -1L2)); static assert(!(-1L2)); static assert(__traits(compiles, 2-1L)); static assert(2-1L); // 2. signed.min = 0 static assert(__traits(compiles, uicast(int)2)); static assert(__traits(compiles, cast(int)2ui)); static assert(__traits(compiles, ulcast(int)2)); static assert(__traits(compiles, cast(int)2ul)); // 3. unsigned.max typeof(unsigned.max/2) static assert(__traits(compiles, icast(uint)2)); static assert(__traits(compiles, cast(uint)2i)); static assert(__traits(compiles, cast(int)-1cast(uint)3)); static assert(__traits(compiles, cast(uint)3cast(int)-1)); static assert(__traits(compiles, -12UL)); static assert(!(-12UL)); static assert(__traits(compiles, 2UL-1)); static assert(2UL-1); // error static assert(!__traits(compiles, ul-2)); static assert(!__traits(compiles, -2ul)); static assert(!__traits(compiles, iul)); static assert(!__traits(compiles, uli)); static assert(!__traits(compiles, lul)); static assert(!__traits(compiles, ull)); static assert(!__traits(compiles, iui)); static assert(!__traits(compiles, uii)); void main(){} -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #45 from Lionello Lunesu lio+bugzi...@lunesu.com 2013-04-10 09:20:22 PDT --- uint b; if (b -2) { ... } The integral expression -2 doesn't have any size per se, but whole size thing shouldn't even apply here, since the two expressions have ranges that are completely disjoint. Points 2 and 3 won't catch this case either and would cause an error. We could consider all integrals 'long' and apply point 1. Or, test for disjoint ranges and replace the whole comparison with a constant? (I have a feeling this optimization might already be happening in a later pass?) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #46 from Andrei Alexandrescu and...@erdani.com 2013-04-10 09:45:57 PDT --- (In reply to comment #45) uint b; if (b -2) { ... } The integral expression -2 doesn't have any size per se, but whole size thing shouldn't even apply here, since the two expressions have ranges that are completely disjoint. Points 2 and 3 won't catch this case either and would cause an error. We could consider all integrals 'long' and apply point 1. Or, test for disjoint ranges and replace the whole comparison with a constant? (I have a feeling this optimization might already be happening in a later pass?) I'd say we need to make this an error. If we don't (i.e. make the comparison always true), then we'd silently change behavior. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #42 from Lionello Lunesu lio+bugzi...@lunesu.com 2013-04-09 03:02:20 PDT --- Yes, I'll have this done this week. For point 1: how to cope with the fact that I can safely cast an uint to long, but can't cast an int to an ulong (without issues)? Surely cast(int)-1 cast(ulong)1 should evaluate to true? But according to point 1 it would be rewritten as cast(ulong)-1 cast(ulong)1 which is 0x 0x1 and evaluate to false. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #43 from Stewart Gordon s...@iname.com 2013-04-09 05:21:52 PDT --- (In reply to comment #42) Yes, I'll have this done this week. For point 1: how to cope with the fact that I can safely cast an uint to long, but can't cast an int to an ulong (without issues)? Surely cast(int)-1 cast(ulong)1 should evaluate to true? But according to point 1 it would be rewritten as cast(ulong)-1 cast(ulong)1 which is 0x 0x1 and evaluate to false. No. Point 1 is the case where a.sizeof b.sizeof. This isn't the case here. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #39 from Andrei Alexandrescu and...@erdani.com 2013-04-08 07:21:23 PDT --- Thanks Lionello for taking this over. I thought of one more case this morning so let me insert in the food chain: (Recall a is signed and b is unsigned.) == 1. If a.sizeof b.sizeof, then a b is lowered into a cast(typeof(a)) b. Then signed comparison proceeds normally. This is a classic value-based conversion dating from the C days, and we do it in D as well. 2. Otherwise, if a is determined through Value Range Propagation to be greater than or equal to zero, then a b is lowered into cast(U) a b, where U is the unsigned variant of typeof(a). Then unsigned comparison proceeds normally. 3. (NEW) Otherwise, if b is determined through Value Range Propagation to be less than or equal to typeof(b).max / 2, then a b is lowered into a cast(S) b, where S is the signed variant of typeof(b). Then signed comparison proceeds normally. 4. Otherwise, the comparison is in error. The error message may recommend using the std.traits.unsigned function, which executes a size-informed cast. == -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #40 from Stewart Gordon s...@iname.com 2013-04-08 15:57:45 PDT --- Sounds good but ... given that people have been trying for 7 years without success to implement the basic rule from the spec, how many more years can we realistically expect it to be before this new scheme being suggested is in the compiler? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #41 from Andrei Alexandrescu and...@erdani.com 2013-04-08 16:14:12 PDT --- (In reply to comment #40) Sounds good but ... given that people have been trying for 7 years without success to implement the basic rule from the spec, how many more years can we realistically expect it to be before this new scheme being suggested is in the compiler? Now that we have a preapproved solution, a solid VRP implementation, and a much expanded contribution base, I can only assume it'll take days. Lionello? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Walter Bright bugzi...@digitalmars.com changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution||WONTFIX --- Comment #27 from Walter Bright bugzi...@digitalmars.com 2013-04-07 01:27:07 PDT --- I think we're going to have to give up on this one. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #28 from Denis Shelomovskij verylonglogin@gmail.com 2013-04-07 20:42:55 MSD --- (In reply to comment #27) I think we're going to have to give up on this one. Not being able to at least highlight signed to unsigned comparisons in a program is a major lack of functionality. IMHO this is why enhancement Issue 9811 matters as it is the place where we can forget about disruptiveness and is it always and error questions. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #29 from Andrei Alexandrescu and...@erdani.com 2013-04-07 15:03:49 PDT --- (In reply to comment #27) I think we're going to have to give up on this one. This is a bit abrupt. What was the decision process? I just shared an anecdote about a few major bugs at work caused by this exact behavior. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #30 from Walter Bright bugzi...@digitalmars.com 2013-04-07 15:49:14 PDT --- (In reply to comment #29) This is a bit abrupt. What was the decision process? I just shared an anecdote about a few major bugs at work caused by this exact behavior. It's been 7 years of discussion now without an answer that works. I don't think it's abrupt! -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #31 from Stewart Gordon s...@iname.com 2013-04-07 16:02:40 PDT --- (In reply to comment #30) (In reply to comment #29) This is a bit abrupt. What was the decision process? I just shared an anecdote about a few major bugs at work caused by this exact behavior. It's been 7 years of discussion now without an answer that works. I don't think it's abrupt! How does pull request 119 not work? And why haven't you written a fix yourself in these 7 years - or even made a single comment on this bug until now? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #32 from Walter Bright bugzi...@digitalmars.com 2013-04-07 16:50:41 PDT --- (In reply to comment #31) How does pull request 119 not work? Follow the links comments https://github.com/D-Programming-Language/dmd/pull/119 If you want to discuss that further, please post there. And why haven't you written a fix yourself in these 7 years - or even made a single comment on this bug until now? I've discussed it extensively on the n.g. This isn't the only place it's come up. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Andrei Alexandrescu and...@erdani.com changed: What|Removed |Added Status|RESOLVED|REOPENED Resolution|WONTFIX | --- Comment #33 from Andrei Alexandrescu and...@erdani.com 2013-04-07 17:24:25 PDT --- Reopening. The entire discussion makes it obvious this needs a fix. It's critical and has 20 votes, probably more than probably any other bug. Closing this without any explanation is straight the opposite of listening to the community. Thanks. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #34 from Walter Bright bugzi...@digitalmars.com 2013-04-07 17:50:06 PDT --- I don't mind if it is reopened. It's just that it's sat at the top of the critical bug list forever with no movement towards a solution. I'd like to get this resolved one way or another. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #35 from Andrei Alexandrescu and...@erdani.com 2013-04-07 18:38:23 PDT --- Great. Here's a solution Walter and I just discussed: Consider a comparison a b, a = b, a b, or a = b, in which a and b are integral types of different signedness. Without loss of generality, let's consider a is signed and b is unsigned and the comparison is a b. Then we have the following cases: 1. If a.sizeof b.sizeof, then a b is lowered into a cast(typeof(a)) b. Then signed comparison proceeds normally. This is a classic value-based conversion dating from the C days, and we do it in D as well. 2. Otherwise, if a is determined through Value Range Propagation to be greater than or equal to zero, then a b is lowered into cast(U) a b, where U is the unsigned variant of typeof(a). Then unsigned comparison proceeds normally. 3. Otherwise, the comparison is in error. The error message may recommend using the std.traits.unsigned function, which executes a size-informed cast. Walter, if you agree with this resolution please mark this as preapproved. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #36 from Andrei Alexandrescu and...@erdani.com 2013-04-07 18:57:27 PDT --- Preapproved FTW! Who wants to implement this? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Andrei Alexandrescu and...@erdani.com changed: What|Removed |Added AssignedTo|bugzi...@digitalmars.com|nob...@puremagic.com --- Comment #37 from Andrei Alexandrescu and...@erdani.com 2013-04-07 19:05:56 PDT --- Resetting asignee to default. If anyone wants to work on this, please assign it to yourself! -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #38 from bearophile_h...@eml.cc 2013-04-07 19:29:00 PDT --- (In reply to comment #35) 3. Otherwise, the comparison is in error. The error message may recommend using the std.traits.unsigned function, which executes a size-informed cast. This is the source of unsigned: auto unsigned(T)(T x) if (isIntegral!T) { static if (is(Unqual!T == byte )) return cast(ubyte ) x; else static if (is(Unqual!T == short)) return cast(ushort) x; else static if (is(Unqual!T == int )) return cast(uint ) x; else static if (is(Unqual!T == long )) return cast(ulong ) x; else { static assert(T.min == 0, Bug in either unsigned or isIntegral); return cast(Unqual!T) x; } } Is it better to use template constraints there? And isn't it better for unsigned to accept only unsigned Ts? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Denis Shelomovskij verylonglogin@gmail.com changed: What|Removed |Added CC||verylonglogin@gmail.com --- Comment #26 from Denis Shelomovskij verylonglogin@gmail.com 2013-03-05 10:44:52 MSK --- Issue state: dmd pull #444 https://github.com/D-Programming-Language/dmd/pull/444 was merged, then #ifdef'd out as it was too disruptive in https://github.com/D-Programming-Language/dmd/commit/52d8c150ecfbe2cad6672f50094a6ff1230e72e3 then completely removed in dmd pull #1611 https://github.com/D-Programming-Language/dmd/pull/1611 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Jesse Phillips jesse.k.phillip...@gmail.com changed: What|Removed |Added CC||jesse.k.phillip...@gmail.co ||m Target Milestone|--- |2.059 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #23 from bearophile_h...@eml.cc 2011-11-25 02:32:32 PST --- I think Walter is willing to accept that patch if someone improves the patch to remove some of its false positives. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #24 from Don clugd...@yahoo.com.au 2011-11-25 04:05:29 PST --- It seems wrong to me that: if (-1 2u) {...} fails to compile. Both are in the range -int.max .. int.max, so they can safely be compared using signed comparison. The problems with mixed sign are when one operand can be in the range -int.max..0 and the other can be in the range int.max+1u..uint.max. If at least one of the operands is in the polysemous range 0..int.max, there should be no problem. But, the patch as it stands allows a polysemous-ranged int to be compared with a uint, but does not allow a polysemous-range uint to be compared with an int. At present the spec doesn't give any reason for unsigned to be treated from signed. The problem is the silly C promotion rule that converts both operands to unsigned (instead, it should generate an error). In any existing C code that works, it works because the signed operand is in the polysemous range. Of course there could be code which relies on (-12u) being false. But surely such code is broken. Do we really need to retain backwards compatibility with broken C code? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #25 from bearophile_h...@eml.cc 2011-11-25 04:26:23 PST --- (In reply to comment #24) Thank you Don. Of course there could be code which relies on (-12u) being false. But surely such code is broken. I don't like this is in D. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 bearophile_h...@eml.cc changed: What|Removed |Added CC||bearophile_h...@eml.cc --- Comment #21 from bearophile_h...@eml.cc 2011-11-24 17:45:34 PST --- See: https://github.com/D-Programming-Language/dmd/commit/4536fd5e3102fcea168660e9c4d2a2c80d50e7f5 But druntime and Phobos will probably need some changes. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #22 from bearophile_h...@eml.cc 2011-11-24 19:25:19 PST --- (In reply to comment #21) But druntime and Phobos will probably need some changes. Keeping this as a warning in the current compiler, and turn it into an (deprecated) error in the next DMD version, will probably allow to update druntime and Phobos. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Christian Kamm kamm-removet...@incasoftware.de changed: What|Removed |Added CC||kamm-removethis@incasoftwar ||e.de --- Comment #20 from Christian Kamm kamm-removet...@incasoftware.de 2011-10-10 08:58:59 PDT --- See https://github.com/D-Programming-Language/dmd/pull/119 https://github.com/D-Programming-Language/dmd/pull/444 for two possible fixes. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 �ric Esti�venart eric.estieven...@free.fr changed: What|Removed |Added CC||eric.estieven...@free.fr --- Comment #19 from �ric Esti�venart eric.estieven...@free.fr 2011-01-14 11:55:24 PST --- Indeed this is rather critical; I hit it in a simple precondition like: void insert( Object o, int ndx = -1 ) // -1 means last in { assert( ndx = -1 ndx = somearray.length ); } forcing to add a cast everywhere would be very painful... The following code should compile without error and pass: void main() { uint ulen = 0; int ndx = -1; assert( -1 = ulen ); assert( ndx = ulen ); } If it generates warnings is another issue... // This one should compile too void func2() { uint u; // should not compile (or at least warn): always yields to true static assert( !is( typeof( u = 0 ) ) ); static assert( !is( typeof( u = -1 ) ) ); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Andrei Alexandrescu and...@metalanguage.com changed: What|Removed |Added Severity|major |critical --- Comment #18 from Andrei Alexandrescu and...@metalanguage.com 2010-11-26 10:43:45 PST --- Escalating severity of this dangerous issue. Has 11 votes, too. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Witold Baryluk bary...@smp.if.uj.edu.pl changed: What|Removed |Added CC||bary...@smp.if.uj.edu.pl --- Comment #17 from Witold Baryluk bary...@smp.if.uj.edu.pl 2009-11-18 13:13:14 PST --- Hi, I today found remarkable bug: int k = -1; uint n = 7; assert(k n); Code above should execute without proble, but dmd it computing false as value of (kn) which absolutly nonsensical. casting n to int, resolves problem int k = -1; uint n = 7; assert(k cast(T)n); How it can be so long time not resolved? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #15 from Don clugd...@yahoo.com.au 2009-09-08 09:40:30 PDT --- (In reply to comment #14) Okay, so what I have is it checks for [snip] signed cmp unsigned or vice versa is okay if the signed arg is a literal and its value is nonnegative. In D2, it's possible to a lot better than this. With the new D2 rules for implicit conversion between integral types (range-based), it should be enough to require that one of the types must implicitly convert to the other. This doesn't quite work yet, since range-based addition (for example) is not yet implemented. This will mean that stuff like: byte b; uint u; b = -67; if (u b + 0x100) ... is OK because although b + 0x100 is signed, it can never be less than 1, so it can safely be converted to unsigned. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #16 from Ellery Newcomer ellery-newco...@utulsa.edu 2009-09-08 10:43:00 PDT --- Cool. That sounds like a much better solution than the patch I posted. Concerning my patch, I just realized that comparison with unsigned and zero generally doesn't make sense either, except maybe {unsigned} 0 so now I have if ( e1-type-isintegral() e2-type-isintegral()){ if(e1-type-isunsigned() ^ e2-type-isunsigned()){ if(!e1-type-isunsigned() dynamic_castIntegerExp*(e1)){ sinteger_t v1 = ((sinteger_t) e1-toInteger()); if(v1 0) goto JustKidding; // 0 uns or 0 != uns okay else if(v1 == 0 (op == TOKlt || op == TOKul)) goto JustKidding; }else if(dynamic_castIntegerExp*(e2)){ sinteger_t v2 = ((sinteger_t) e2-toInteger()); if(v2 0) goto JustKidding; // uns 0 or uns != 0 okay else if(v2 == 0 (op == TOKgt || op == TOKug)) goto JustKidding; } error(comparing signed and unsigned integers); } JustKidding:; } in case anyone plans to commit it -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Ellery Newcomer ellery-newco...@utulsa.edu changed: What|Removed |Added CC||ellery-newco...@utulsa.edu --- Comment #12 from Ellery Newcomer ellery-newco...@utulsa.edu 2009-09-03 08:33:41 PDT --- This morning I've been tinkering with the DMD source, and I've made an edit to expression.c that appears to fix this issue. How do I submit? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #14 from Ellery Newcomer ellery-newco...@utulsa.edu 2009-09-03 13:51:16 PDT --- Okay, so what I have is it checks for signed cmp unsigned or vice versa in CmpExp::Semantic just before typeCombine gets called, which works, but then stuff like 1 1u doesn't. So the idea is signed cmp unsigned or vice versa is okay if the signed arg is a literal and its value is nonnegative. This should work fine if sizeof(signed arg) = sizeof(unsigned arg) because the value of the signed arg is within the range of the unsigned arg, and typeCombine should be able to expand the type of the signed arg to that of the unsigned arg or whatever. It should work if sizeof(signed arg) sizeof(unsigned arg) because the value of the unsigned arg is within the range of the signed arg, and typeCombine should be able to expand the type of the unsigned arg to that of the signed arg. I don't know, maybe this should be happening in typeCombine. Insert the following in expression.c CmpExp::semantic before the line typeCombine(sc); if ( e1-type-isintegral() e2-type-isintegral()){ if(e1-type-isunsigned() ^ e2-type-isunsigned()){ if(!e1-type-isunsigned() dynamic_castIntegerExp*(e1) ((sinteger_t) e1-toInteger()) = 0) goto JustKidding; if(!e2-type-isunsigned() dynamic_castIntegerExp*(e2) ((sinteger_t) e2-toInteger()) = 0) goto JustKidding; error(comparing signed and unsigned integers); } JustKidding:; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Andrei Alexandrescu and...@metalanguage.com changed: What|Removed |Added Status|NEW |ASSIGNED CC||and...@metalanguage.com AssignedTo|nob...@puremagic.com|and...@metalanguage.com --- Comment #10 from Andrei Alexandrescu and...@metalanguage.com 2009-07-24 18:08:49 PDT --- This needs to be fixed. I'm taking ownership (though Walter will do all the work) in order to not forget. I'll add a unittest to TDPL too. Until then let's vote this up. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 Qian Xu qian...@funkwerk-itk.com changed: What|Removed |Added CC||qian...@funkwerk-itk.com --- Comment #7 from Qian Xu qian...@funkwerk-itk.com 2009-07-22 00:31:06 PDT --- Is there any official response to this issue? It was reported at 2006, but the status is still NEW -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #9 from Qian Xu qian...@funkwerk-itk.com 2009-07-22 01:34:05 PDT --- (In reply to comment #8) As I look, bug 2006 doesn't seem to have anything to do with this one at all. But if you find a duplicate of a bug, then mark it as one! sorry, i mean it was reported in year 2006. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #3 from clugd...@yahoo.com.au 2009-02-23 02:28 --- Note that it's critical than any fix for this bug should not make code like the following fail to compile: uint a = 5; if (a 2) { ... } Otherwise the cure would be worse than the disease g. --
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #4 from ddparn...@bigpond.com 2009-02-23 02:34 --- Even more critical, any fix for this bug should not make code like the following fail to compile: uint a = 5; if (a -2) { ... } --
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 --- Comment #5 from 2kor...@gmail.com 2009-02-23 07:40 --- (In reply to comment #4) Even more critical, any fix for this bug should not make code like the following fail to compile: uint a = 5; if (a -2) { ... } Why not? This is obviously a bug! --
[Issue 259] Comparing signed to unsigned does not generate an error
http://d.puremagic.com/issues/show_bug.cgi?id=259 s...@iname.com changed: What|Removed |Added CC||o.da...@gmx.de --- Comment #2 from s...@iname.com 2009-02-22 11:45 --- *** Bug 2205 has been marked as a duplicate of this bug. *** --