Out of bound problem
Christopher Wright
dhasenan at gmail.com
Sat Feb 16 18:58:08 PST 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 instantiating
Ouch! 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
More information about the Digitalmars-d-learn
mailing list