Static array as immutable

Nathan S. no.public.email at example.com
Tue Dec 12 15:30:01 UTC 2017


On Tuesday, 12 December 2017 at 11:37:40 UTC, Jonathan M Davis 
wrote:
> On Tuesday, December 12, 2017 10:35:15 Ivan Trombley via 
> Digitalmars-d-learn wrote:
>> On Tuesday, 12 December 2017 at 09:48:09 UTC, Jonathan M Davis
>>
>> wrote:
>> > On Tuesday, December 12, 2017 07:33:47 Ivan Trombley via
>> >
>> > Digitalmars-d-learn wrote:
>> >> Is there some way that I can make this array immutable?
>> >>
>> >>    static float[256] ga = void;
>> >>    static foreach (i; 0 .. 256)
>> >>
>> >>        ga[i] = (i / 255.0f) ^^ (1 / 2.2f);
>> >
>> > If you want anything to be immutable, you either have to 
>> > initialize it directly or give it a value in a static 
>> > constructor (and the static constructor solution won't work 
>> > for local variables). So, you'd need to do something like
>> >
>> > static immutable float[256] ga = someFuncThatGeneratesGA();
>> >
>> > If the function is pure, and there's no way that the return 
>> > value was passed to the function, then its return value can 
>> > be assigned to something of any mutability, since the 
>> > compiler knows that there are no other references to it, and 
>> > it can implicitly cast it, or if the type is a value type 
>> > (as in this case), then you just get a copy, and mutability 
>> > isn't an issue. Alternatively to using a pure function, you 
>> > can use std.exception.assumeUnique to cast to immutable, but 
>> > that relies on you being sure that there are no other 
>> > references to the data, and it may not work at compile-time, 
>> > since casting is a lot more restrictive during CTFE. So, in 
>> > general, using a pure function is preferable to assumeUnique.
>> >
>> > - Jonathan M Davis
>>
>> Ah, it doesn't work. I get this error using the ^^ operator:
>>
>> /usr/include/dmd/phobos/std/math.d(5724,27): Error: cannot
>> convert &real to ubyte* at compile time
>> /usr/include/dmd/phobos/std/math.d(6629,24):        called from
>> here: signbit(x)
>> /usr/include/dmd/phobos/std/math.d(6756,16):        called from
>> here: impl(cast(real)x, cast(real)y)
>>
>> :(
>
> Well, if the code you need to initialize a variable can't be 
> run at compile time, then that variable can't be a variable 
> that needs to be initialized at compile time and be immutable.
>
> - Jonathan M Davis

While what you're saying is true, exponentiation not being 
runnable at compile-time is a defect and I would assume a 
regression. I'll file a bug report. FWIW when trying to run the 
following with DMD v2.077.1 I get:

```
void main(string[] args)
{
     import std.stdio;
     enum e = (1.0 / 255.0f) ^^ (1 / 2.2f);
     writeln("e = ", e);
}
```

=>

[...]/dmd/std/math.d(440): Error: y.vu[4] is used before 
initialized
[...]/dmd/std/math.d(413):        originally uninitialized here
[...]/dmd/std/math.d(4107):        called from here: floorImpl(x)
[...]/dmd/std/math.d(2373):        called from here: floor(x + 
0.5L)
[...]/dmd/std/math.d(2110):        called from here: exp2Impl(x)
[...]/dmd/std/math.d(6743):        called from here: exp2(yl2x(x, 
y))
[...]/dmd/std/math.d(6756):        called from here: 
impl(cast(real)x, cast(real)y)


More information about the Digitalmars-d-learn mailing list