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,
bearophile
I 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,
bearophile
As 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









Denton Cockburn <diboss hotmail.com> 