Fixing const arrays

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sat Dec 10 13:47:13 PST 2011


Walter and I discussed today and decided to fix this long-standing issue:

import std.algorithm;
void main() {
   const arr = [1, 2, 3];
   reduce!"a*b"(arr);
}

The problem here is that D's built-in arrays are at the same time 
containers and their own ranges. When the array is constant the matter 
becomes confusing because the range itself must be non-constant such 
that it can iterate the constant array.

Put simply, the type of the array in this case should be const(int[]) 
and the type of its range should be const(int)[].

This problem does not commonly occur with ranges because people do 
expect that a constant range can't be used for iteration, and an 
elaborate container will emit the proper type of range even when the 
container itself is constant.

We decided to fix this issue by automatically shedding the top-level 
const when passing an array or a pointer by value into a function.

The rule is simple and does not complicate lookup rules, type deduction, 
or template specialization. It is a semantic rewrite as follows.

Consider x an array of type qualifier(T[]). In any function call in 
which it is established that x is passed by value (i.e. no "ref" with 
the parameter), the call:

fun(..., x, ...)

is lowered into:

fun(..., cast(qualifier(T)[]) x, ...)

after which the usual language rules apply. Similarly, if x has type 
qualifier(T*), AND if x is passed by value into a function, the call:

fun(..., x, ...)

is lowered into:

fun(..., cast(qualifier(T)*) x, ...)

after which, again, the usual rules apply. Note that fun does not need 
to be a template and generally must meet no special conditions aside 
from taking x by value. If fun takes specifically a const(T[]), the call 
will go through no problem because const(T)[] is implicitly convertible 
to const(T[]).

This allows template functions to accept arrays by value yet modify 
their own private copy of the array's bounds, which is reasonable and 
expected.

This rule solves a host of issues related to applying range algorithms 
to arrays. I hope we will have this rule in action in dmd 2.057.


Andrei


More information about the Digitalmars-d mailing list