Providing implicit conversion of - memory-safety

Renato renato at athaydes.com
Tue Jan 23 21:40:46 UTC 2024


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).


More information about the Digitalmars-d-learn mailing list