Challenge: write a reference counted slice that works as much as possible like a built-in slice

Paul Backus snarwin at gmail.com
Sat Nov 13 00:29:07 UTC 2021


On Friday, 12 November 2021 at 22:09:28 UTC, Andrei Alexandrescu 
wrote:
> On 2021-11-12 16:14, Timon Gehr wrote:
>> You still need language support. Reaching mutable data through 
>> an immutable pointer violates transitivity assumptions.
>
> Indeed, but not indirectly. You can soundly access a pointer to 
> mutable data if you use the immutable pointer as a key in a 
> global hashtable.

I guess the question reduces to: what is the simplest thing you 
can do to a pointer that will make the compiler forget its 
provenance?

Adding an offset is clearly not enough. Casting it to an integer, 
taking its hash, and using that hash to look up a value in an 
associative array is probably *more* than enough. Is there 
something in between that's "just right"?

One possibility is casting the pointer to an integer, and then 
immediately casting it back:

     immutable(int)* p;
     size_t n = cast(size_t) (p - 1);
     int* q = cast(int*) n;
     *q = 123;

Assume we know, somehow, that the memory location pointed by q is 
allocated and contains a mutable int. Does the mutation in the 
final line have undefined behavior?

The answer depends on whether integers have provenance or not--a 
question which remains unsettled in the world of C and C++. [1] 
If we decide that integers should *not* have provenance in D, 
then the above code is valid, and we do not need to add any new 
features to the type system to support it.

The downsides of this approach are:

   1) Understanding and maintaining code that relies on obscure 
language rules like this is really difficult.
   2) Existing compiler backends (GCC, LLVM) don't always handle 
code like this correctly, even in C. (See linked article.)

[1] https://www.ralfj.de/blog/2020/12/14/provenance.html


More information about the Digitalmars-d mailing list