Run-time setting of immutable variable?

DLearner bmqazwsx123 at gmail.com
Thu Sep 2 17:17:15 UTC 2021


On Thursday, 2 September 2021 at 16:46:46 UTC, Steven 
Schveighoffer wrote:
> On 9/2/21 12:01 PM, DLearner wrote:
>> Suppose there is a variable that is set once per run, and is 
>> (supposed) never to be altered again.  However, the value to 
>> which it is set is not known at compile time.
>> Example below, variable is 'ArrPtr';
>> ```
>> ubyte[10] Arr;
>> 
>> // immutable void* ArrPtr;
>> void* ArrPtr;
>> 
>> void main() {
>> 
>>     ArrPtr = cast(void*)Arr[0];
>> 
>> // <Lots of code depending on ArrPtr, but not supposed to 
>> modify ArrPtr>
>> 
>> }
>> ```
>> Is there a way of getting D to guarantee that ArrPtr is never 
>> modified after
>> ```
>>     ArrPtr = cast(void*)Arr[0];
>> ```]
>
> You shouldn't be doing this. `Arr` is not immutable, so 
> `ArrPtr` shouldn't point at it if it's immutable.
>
> If you want to guarantee that `ArrPtr` never changes once set, 
> yet still want it to point at mutable data, you need to use a 
> type that does that (like a head mutable or "write once" type), 
> which I believe doesn't exist in phobos.
>
> If you don't actually need to mutate the data via `ArrPtr`, you 
> can make it const, and use H.S. Teoh's solution. But you should 
> not use immutable, as the compiler implies that data pointed at 
> is also immutable (and of course, you won't need casting). Make 
> sure you use regular `static this`, not `shared static this`, 
> as your fields are thread-local, not shared.
>
> -Steve

The following clean-compiled and produced the expected result:
```
     ubyte[10] Arr;

     immutable void* ArrPtr;
	shared static this() {
		ArrPtr = cast(immutable void*)(&Arr[0]);
	}

	void main() {
	
	  import std.stdio;
       void* ArrPtr2;

       ArrPtr2 = cast(void*)(&Arr[0]);
		
       writeln("ArrPtr = ", ArrPtr);
       writeln("ArrPtr2 = ", ArrPtr2);  // consistency test

//      ArrPtr = ArrPtr + 1;  // mutability test - compile 
(correctly) failed when uncommented.
       ArrPtr2 = ArrPtr2 + 1;
	
       Arr[1] = 4;
	  Arr[1] = 7;  // mutability test	
	}
```

The following produced deprecated warnings, but still seemed to 
work:
```
     ubyte[10] Arr;

     immutable void* ArrPtr;
	static this() {
		ArrPtr = cast(immutable void*)(&Arr[0]);
	}

	void main() {
	
	  import std.stdio;
       void* ArrPtr2;

       ArrPtr2 = cast(void*)(&Arr[0]);
		
       writeln("ArrPtr = ", ArrPtr);
       writeln("ArrPtr2 = ", ArrPtr2);  // consistency test

//      ArrPtr = ArrPtr + 1;  // mutability test on ArrPtr - 
compile (correctly) failed when uncommented.
       ArrPtr2 = ArrPtr2 + 1;
	
       Arr[1] = 4;
	  Arr[1] = 7;  // mutability test on Arr
	}
```
I am looking for a mutable Arr but would like an immutable ArrPtr.

```
`Arr` is not immutable, so `ArrPtr` shouldn't point at it if it's 
immutable.
```
Surely there is no inconsistency - at run time the array is in a 
fixed place,  so ArrPtr is (or at least should be) a constant, 
but the contents of the array
can vary as the program runs.


More information about the Digitalmars-d-learn mailing list