Request: a more logical static array behavior

Tommi tommitissari at hotmail.com
Thu Aug 15 05:12:57 PDT 2013


On Thursday, 15 August 2013 at 02:30:54 UTC, Jonathan M Davis 
wrote:
> On Thursday, August 15, 2013 02:57:25 Tommi wrote:
>> Thus, my point is this:
>> Shouldn't this magical property of static arrays (implicitly
>> converting to dynamic array during type deduction) extend to 
>> all
>> type deduction situations?
>
> No. If anything, we should get rid of the implicit conversion 
> from a static
> array to a dynamic one. It's actually unsafe to do so. It's 
> just like if you
> implicitly converted a local variable to the address of that 
> local variable
> when you passed it to a function that accepted a pointer. IMHO, 
> it never
> should have been allowed in the first place. At least with 
> taking the address
> of a local variable, the compiler treats it as @system. The 
> compiler doesn't
> currently do that with taking the slice of a static array.
>
> http://d.puremagic.com/issues/show_bug.cgi?id=8838
>
> If you want a dynamic array from a static one, then slice it. 
> That works just
> fine with templated functions, and makes what you want 
> explicit. Also, making
> it so that IFTI instantiated templates with the dynamic array 
> type when given
> a static array would make it so that you would have to 
> explicitly instantiate
> any templates where you actually wanted to pass a static array, 
> which is a
> definite negative IMHO.
>
> At this point, I don't really expect that it'll be changed so 
> that static
> arrays do not implicitly convert to dynamic ones (much as it 
> would be ideal to
> make that change), but I really don't think that we should do 
> anything to make
> the problem worse by adding yet more such implicit conversions.
>
> - Jonathan M Davis

Now I feel like these three different notions are getting 
somewhat conflated:
1) memory safety
2) implicit conversion
3) implicit conversion during type deduction

Memory safety
-------------
If the following code is treated as @system code (which it is):

void getLocal(int* p) { }

void main()
{
     int n;
     getLocal(&n);
}

...then the following code should be treated as @system code as 
well (which it currently isn't):

void getLocal(int[] da) { }

void main()
{
     int[5] sa;
     getLocal(sa[]); // Notice the _explicit_ conversion
}

...There's no two ways about it. But implicit conversion has 
nothing to do with this. If you want to disallow implicit 
conversion because it's a bug prone programming construct, then 
you have a valid reason to do so (and it would be fine by me). 
But if you want to disallow implicit conversion from static array 
to a slice because it's not _always_ memory safe, then you're 
doing it for the wrong reason: e.g. the following code is memory 
safe even though we're using the implicit conversion:

void getGlobal(int[] da) { }
int[5] gsa;

void main()
{
     getGlobal(gsa); // implicit conversion
}

Like I said: implicit conversion doesn't really have anything to 
do with the potential memory safety issues.

Implicit conversion VS Implicit conversion during type deduction
----------------------------------------------------------------
I don't think that you failed to see the distinction between 
these two things, but because someone might, I'll talk about this 
a bit more.

This is regular implicit conversion (nothing weird or magical 
about it):

void foo(int[] da) { }
int[3] sa;
foo(sa); // implicit conversion

This is implicit conversion during type deduction (totally weird 
and magical):

void foo(T)(T[] da) { }
int[3] sa;
foo(sa); // implicit conversion during type deduction

That above example about implicit conversion during type 
deduction is like writing the following C++ code and having it 
actually compile:

template <typename T>
struct DynamicArray { };

template <typename T>
struct StaticArray {
     operator DynamicArray<T>() const
     {
         return DynamicArray<T>{};
     }
};

template <typename T>
void foo(DynamicArray<T> da) { }

void bar(DynamicArray<int> da) { }

int main(int argc, char *argv[])
{
     StaticArray<int> sa;
     foo((DynamicArray<int>)sa); // OK: explicit conversion
     bar(sa); // OK: regular implicit conversion
     foo(sa); // Error: No matching function call to 'foo'
     return 0;
}

It is this implicit conversion during type deduction that makes 
D's static arrays' behavior illogical and inconsistent (because 
it doesn't happen in all type deduction contexts). Whereas 
regular implicit conversion may be a dangerous or an unsafe 
programming tool, there's nothing illogical about it.

I don't want to increase the number of implicit conversions. All 
I'm trying to do is make D's static arrays behave more logically. 
And there are two ways to do this:
1) make static arrays free to implicitly convert to dynamic array 
in all type deduction situations
2) disallow static arrays from implicitly converting during type 
deduction

Notice that in order to make static arrays' behavior logical, 
there's no need to disallow them from implicitly converting to 
dynamic arrays in the general sense (just during type deduction).


More information about the Digitalmars-d mailing list