On Tuesday, 23 January 2024 at 21:18:53 UTC, bachmeier wrote:
There are two things things that cause the problem. One is the
use of a template and the other is passing an unsigned type.
The reason the first parameter uses a template is because there
are a lot of types I could send as the first argument, and for
some of them there was a transformation of index (for instance,
you can pass a date as a long[2], or you can pass another type
and pull out the length, that sort of thing). It's using a
pointer because I was working with a C library, and that's how
the data is stored and passed around.
The data is time series. If after the transformations the index
is less than zero, it returns 0.0, which is used for all
pre-sample values. If it's non-negative, return the element at
that position.
One of the nice things about D is the ability to write this
kind of code in such a natural and (I thought) intuitive style.
I really like the way all this comes together. There's really
no way that code should have been able to do anything wrong.
What's terribly frustrating is that the compiler had full
knowledge of what was happening, but by choice it didn't say
anything, even though D is supposed to prevent these things
that happen in C.
While I can understand your frustration, it seems to me D is not
to blame in this instance because the code is quite patently
using unsafe constructs (D does not claim to be fully safe).
Would something like this work?
```d
double value(T)(T index, double* x) if (is(T : size_t))
{
if (index < 5 || x == null)
{
return 0.0;
}
else
{
return x[index - 5];
}
}
void main()
{
import std.stdio;
import std.range : iota;
double[] ds = [1, 2, 3, 4, 5, 6];
ubyte b = 1;
foreach (_; iota(12))
{
writeln(value(b++, ds.ptr));
}
}
```
This will still read rubbish if the index goes past the actual
array (because I assume you can't get the exact length from the C
code? If you can, you should pass that in and do the bounds check
yourself) but there's no unsigned type mistakes (notice that it's
almost always a mistake to subract from any unsigned type - D
scanner correctly warns about that).