digitalmars.D.learn - Out of bound problem
- bearophile (27/27) Feb 16 2008 While testing I have found a problem in my code, I have reduced the code...
- Denton Cockburn (3/42) Feb 16 2008 I tried looking at this. It's weird (and tripping me out).
- Neil Vice (7/36) Feb 16 2008 As far as I can tell the cause is that the expression b[0] is being
- Denton Cockburn (3/51) Feb 16 2008 Behaviour exists in DMD 2.010 and GDC 0.25(1.021)
- Christopher Wright (18/53) Feb 16 2008 ...
- Sergey Gromov (14/25) Feb 16 2008 But how the compiler should handle this ? In trivial case above, the
- bearophile (19/20) Feb 17 2008 Thanks to everybody, in my code I did solve the problem like this:
- Christopher Wright (9/34) Feb 17 2008 std.traits.isArray/isStaticArray/isDynamic doesn't work? I don't recall
- bearophile (4/6) Feb 17 2008 You are right, thank you. I'm learning D still.
- Christopher Wright (5/12) Feb 17 2008 Not many people using D spend a lot of time spelunking in the bowels of
- Bill Baxter (4/15) Feb 17 2008 ...and since the syntax for 'is' expressions make about as much sense as...
- Christopher Wright (5/22) Feb 17 2008 Now, now. No cross, no crown, no green sword. If you want to start a
- Christopher Wright (2/4) Feb 18 2008 Green sword? I meant green star. It's the symbol for Esperanto.
- Bill Baxter (4/10) Feb 18 2008 I googled the phrase and came up with bupkis.
- Ary Borenszweig (4/16) Feb 18 2008 I think everytime someone mentions Esperanto, all kind of discussions
- Bill Baxter (5/21) Feb 18 2008 Sounds like maybe it means "if you can't say something nice, don't say
- Christopher Wright (2/14) Feb 18 2008 Green star: symbol for Esperanto. Shorthand way of saying 'don't flame'.
- Sergey Gromov (12/25) Feb 16 2008 It seems to replace the line
While testing I have found a problem in my code, I have reduced the code to the following lines: template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } TA[] foo(TA, TB)(TA[] a, TB b) { TA[] result; static if (IsArray!(TB)) { if (b.length == 0) { result = a; } else if (b.length == 1) { result = foo(a, b[0]); } } return result; } void main() { foo("test", ""); } Its output: bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(21): template instance bug.foo!(char,char[0u]) error instantiating I have found ways to solve this problem, but can someone please explain me what's the problem? Bye and thank you, bearophile
Feb 16 2008
On Sat, 16 Feb 2008 19:43:54 -0500, bearophile wrote:While testing I have found a problem in my code, I have reduced the code to the following lines: template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } TA[] foo(TA, TB)(TA[] a, TB b) { TA[] result; static if (IsArray!(TB)) { if (b.length == 0) { result = a; } else if (b.length == 1) { result = foo(a, b[0]); } } return result; } void main() { foo("test", ""); } Its output: bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(21): template instance bug.foo!(char,char[0u]) error instantiating I have found ways to solve this problem, but can someone please explain me what's the problem? Bye and thank you, bearophileI tried looking at this. It's weird (and tripping me out). I would love to see the explanation of what's going wrong here.
Feb 16 2008
"bearophile" <bearophileHUGS lycos.com> wrote in message news:fp800a$2781$1 digitalmars.com...While testing I have found a problem in my code, I have reduced the code to the following lines: template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } TA[] foo(TA, TB)(TA[] a, TB b) { TA[] result; static if (IsArray!(TB)) { if (b.length == 0) { result = a; } else if (b.length == 1) { result = foo(a, b[0]); } } return result; } void main() { foo("test", ""); } Its output: bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(21): template instance bug.foo!(char,char[0u]) error instantiating I have found ways to solve this problem, but can someone please explain me what's the problem? Bye and thank you, bearophileAs far as I can tell the cause is that the expression b[0] is being evaluated even if the enclosing if statement hasn't been entered. For example if the line containing b[0] is replaced with a writef() it is never output to the console. I can only assume that this is a compiler bug.
Feb 16 2008
On Sun, 17 Feb 2008 11:37:53 +0900, Neil Vice wrote:"bearophile" <bearophileHUGS lycos.com> wrote in message news:fp800a$2781$1 digitalmars.com...Behaviour exists in DMD 2.010 and GDC 0.25(1.021)While testing I have found a problem in my code, I have reduced the code to the following lines: template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } TA[] foo(TA, TB)(TA[] a, TB b) { TA[] result; static if (IsArray!(TB)) { if (b.length == 0) { result = a; } else if (b.length == 1) { result = foo(a, b[0]); } } return result; } void main() { foo("test", ""); } Its output: bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(21): template instance bug.foo!(char,char[0u]) error instantiating I have found ways to solve this problem, but can someone please explain me what's the problem? Bye and thank you, bearophileAs far as I can tell the cause is that the expression b[0] is being evaluated even if the enclosing if statement hasn't been entered. For example if the line containing b[0] is replaced with a writef() it is never output to the console. I can only assume that this is a compiler bug.
Feb 16 2008
bearophile wrote:While testing I have found a problem in my code, I have reduced the code to the following lines: template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); }... Y'know, there's a template for this in std.traits and tango.core.Traits.TA[] foo(TA, TB)(TA[] a, TB b) { TA[] result; static if (IsArray!(TB)) { if (b.length == 0) { result = a; } else if (b.length == 1) { result = foo(a, b[0]); } } return result; } void main() { foo("test", ""); } Its output: bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(13): Error: array index 0 is out of bounds b[0 .. 0] bug.d(21): template instance bug.foo!(char,char[0u]) error instantiatingOuch! Constant expansion for the lose! What's going on is, this is being evaluated at compile time, when you've got a runtime check for length. So it's expanded like this: if ("".length == 0) { // blah } else if ("".length == 1) { result = foo(blah, ""[0]); } Then the compiler sees: Array literal! Constant index! Must expand! Obviously, it can't do that. So it gives an error. So, you can use a static if, but that'll fail for a dynamic array. Or you can pass in ""[] rather than "". Or you can check if it's a static array, do a 'static if (array.length)' in that case, and in the case of a dynamic array, use a non-static if. But yeah, it's a bug.I have found ways to solve this problem, but can someone please explain me what's the problem? Bye and thank you, bearophile
Feb 16 2008
Christopher Wright <dhasenan gmail.com> wrote:if ("".length == 0) { // blah } else if ("".length == 1) { result = foo(blah, ""[0]); } Then the compiler sees: Array literal! Constant index! Must expand! Obviously, it can't do that. So it gives an error. [...] But yeah, it's a bug.But how the compiler should handle this ? In trivial case above, the code with error is unreachable. But as a generic solution, it probably should expand into something like: if (condition) { // blah } else if (other condition) { blah; // stays here for possible side effects // ""[0] is replaced with this at compile time throw new ArrayBoundsException(); // the rest of the block is unreachable, throw away } -- SnakE
Feb 16 2008
Thanks to everybody, in my code I did solve the problem like this: result = foo(a, b.dup[0]); But I was curious to know what you think about this situation. Now I know it's probably a compiler bug. Christopher Wright:Y'know, there's a template for this in std.traits and tango.core.Traits.I don't use Tango (yet). I use always the std lib when possible, I know there's no point in duplicating the std lib. I don't remember the bugs or the problems, but I have found std.traits not enough for similar array purposes, and I have found a bug in the traits of Tango to do that array purposes, so I have created IsArray and IsDynamicArray, you can find them in my d libs: template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } template IsDynamicArray(T) { const bool IsDynamicArray = is( typeof(T.init[0])[] == T ); } template IsStaticArray(T) { const bool IsStaticArray = IsArray!(T) && (!IsDynamicArray!(T)); } That IsArray may look a bit like "duck typing at compile time", but that's the only thing that works that I have found. I use similar tools all the time, so I need to have them quite sharp :-) Bye, bearophile
Feb 17 2008
bearophile wrote:Thanks to everybody, in my code I did solve the problem like this: result = foo(a, b.dup[0]); But I was curious to know what you think about this situation. Now I know it's probably a compiler bug. Christopher Wright:std.traits.isArray/isStaticArray/isDynamic doesn't work? I don't recall seeing such a bug report.Y'know, there's a template for this in std.traits and tango.core.Traits.I don't use Tango (yet). I use always the std lib when possible, I know there's no point in duplicating the std lib. I don't remember the bugs or the problems, but I have found std.traits not enough for similar array purposes, and I have found a bug in the traits of Tango to do that array purposes, so I have created IsArray and IsDynamicArray, you can find them in my d libs:template IsArray(T) { const bool IsArray = is(typeof(T.length)) && is(typeof(T.sort)) && is(typeof(T.reverse)) && is(typeof(T.dup)); } template IsDynamicArray(T) { const bool IsDynamicArray = is( typeof(T.init[0])[] == T ); } template IsStaticArray(T) { const bool IsStaticArray = IsArray!(T) && (!IsDynamicArray!(T)); }const bool IsStaticArray(T) { const bool IsStaticArray = is(typeof(T[0])) && is(typeof(T[0])[T.sizeof/T[0].sizeof] == T); } Then, since IsStaticArray doesn't depend on IsArray, you can change IsArray to return true iff IsStaticArray or IsDynamicArray.That IsArray may look a bit like "duck typing at compile time", but that's the only thing that works that I have found. I use similar tools all the time, so I need to have them quite sharp :-) Bye, bearophile
Feb 17 2008
Christopher Wright:Then, since IsStaticArray doesn't depend on IsArray, you can change IsArray to return true iff IsStaticArray or IsDynamicArray.You are right, thank you. I'm learning D still. Bye, bearophile
Feb 17 2008
bearophile wrote:Christopher Wright:Not many people using D spend a lot of time spelunking in the bowels of templates, especially now that CTFE is available. The basics are quite handy, but a lot of it is rather arcane, since the type system allows for quite a bit of freedom.Then, since IsStaticArray doesn't depend on IsArray, you can change IsArray to return true iff IsStaticArray or IsDynamicArray.You are right, thank you. I'm learning D still.Bye, bearophile
Feb 17 2008
Christopher Wright wrote:bearophile wrote:...and since the syntax for 'is' expressions make about as much sense as George W. --bbChristopher Wright:Not many people using D spend a lot of time spelunking in the bowels of templates, especially now that CTFE is available. The basics are quite handy, but a lot of it is rather arcane, since the type system allows for quite a bit of freedom.Then, since IsStaticArray doesn't depend on IsArray, you can change IsArray to return true iff IsStaticArray or IsDynamicArray.You are right, thank you. I'm learning D still.
Feb 17 2008
Bill Baxter wrote:Christopher Wright wrote:Now, now. No cross, no crown, no green sword. If you want to start a flamewar, just talk about const :P Though it does make sense, in a vague, twisted way. You just expect to be able to do some things that don't yet work.bearophile wrote:....and since the syntax for 'is' expressions make about as much sense as George W. --bbChristopher Wright:Not many people using D spend a lot of time spelunking in the bowels of templates, especially now that CTFE is available. The basics are quite handy, but a lot of it is rather arcane, since the type system allows for quite a bit of freedom.Then, since IsStaticArray doesn't depend on IsArray, you can change IsArray to return true iff IsStaticArray or IsDynamicArray.You are right, thank you. I'm learning D still.
Feb 17 2008
Christopher Wright wrote:Now, now. No cross, no crown, no green sword. If you want to start a flamewar, just talk about const :PGreen sword? I meant green star. It's the symbol for Esperanto.
Feb 18 2008
Christopher Wright wrote:Christopher Wright wrote:I googled the phrase and came up with bupkis. Still am clueless as to what you meant even with the correction. :-) --bbNow, now. No cross, no crown, no green sword. If you want to start a flamewar, just talk about const :PGreen sword? I meant green star. It's the symbol for Esperanto.
Feb 18 2008
Bill Baxter escribió:Christopher Wright wrote:I found this: http://archives.conlang.info/pho/zheinfi/wurqanwhian.html :)Christopher Wright wrote:I googled the phrase and came up with bupkis.Now, now. No cross, no crown, no green sword. If you want to start a flamewar, just talk about const :PGreen sword? I meant green star. It's the symbol for Esperanto.Still am clueless as to what you meant even with the correction. :-)I think everytime someone mentions Esperanto, all kind of discussions arise... maybe it's that what he meant?--bb
Feb 18 2008
Ary Borenszweig wrote:Bill Baxter escribió:That doesn't explain it either, just uses the phrase.Christopher Wright wrote:I found this: http://archives.conlang.info/pho/zheinfi/wurqanwhian.html :)Christopher Wright wrote:I googled the phrase and came up with bupkis.Now, now. No cross, no crown, no green sword. If you want to start a flamewar, just talk about const :PGreen sword? I meant green star. It's the symbol for Esperanto.Sounds like maybe it means "if you can't say something nice, don't say anything at all". --bbStill am clueless as to what you meant even with the correction. :-)I think everytime someone mentions Esperanto, all kind of discussions arise... maybe it's that what he meant?
Feb 18 2008
Bill Baxter wrote:Christopher Wright wrote:Green star: symbol for Esperanto. Shorthand way of saying 'don't flame'.Christopher Wright wrote:I googled the phrase and came up with bupkis. Still am clueless as to what you meant even with the correction. :-) --bbNow, now. No cross, no crown, no green sword. If you want to start a flamewar, just talk about const :PGreen sword? I meant green star. It's the symbol for Esperanto.
Feb 18 2008
bearophile <bearophileHUGS lycos.com> wrote:TA[] foo(TA, TB)(TA[] a, TB b) { TA[] result; static if (IsArray!(TB)) { if (b.length == 0) { result = a; } else if (b.length == 1) { result = foo(a, b[0]); } } return result; }It seems to replace the line result = foo(a, b[0]); with result = foo("test", ""[0]); and then complain that the constant expression ""[0] is wrong. It's about distinguishing between static and dynamic arrays which I don't know how to do. In your case, adding static if(b.sizeof) should do the trick: only empty static arrays have zero size. -- SnakE
Feb 16 2008