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