Is D's pointer subtraction more permissive than C (and C++)?

Ali Çehreli acehreli at yahoo.com
Fri Apr 1 15:52:39 UTC 2022


As the following quote from a Microsoft document claims, and as I've 
already known, pointer subtraction is legal only if the pointers are 
into the same array: "ANSI 3.3.6, 4.1.1 The type of integer required to 
hold the difference between two pointers to elements of the same array, 
ptrdiff_t." ( 
https://docs.microsoft.com/en-us/cpp/c-language/pointer-subtraction?view=msvc-170 
)

I suspect "array" means "a block of memory" there because arrays are 
ordinarily malloc'ed pieces of memory in C.

1) Is D more permissive (or anemic in documentation:))? I ask because 
paragraph 5 below does not mention the pointers should be related in any 
way:

   https://dlang.org/spec/expression.html#pointer_arithmetic

2) Is subtracting pointers that used to be in the same array legal.

void main() {
   auto a = [ 1, 2 ];
   auto b = a;
   assert(a.ptr - b.ptr == 0);    // i) Obviously legal?

   // Drop the first element
   a = a[1..$];
   assert(a.ptr - b.ptr == 1);    // ii) GC-behaviorally legal?

   // Save the pointer
   const old_aPtr = a.ptr;
   // and move the array to another memory
   a.length = 1_000_000;
   // Expect a and b are on different blocks of memory
   assert(a.ptr != old_aPtr);

   assert(old_aPtr - b.ptr == 1);  // iii) Practically legal?
}

Regardless of your answer, I will go ahead and perform that last 
subtraction :).

Ali

P.S. I am trying to implement a type where slices will follow the 
elements as the elements may be moved in memory:

   const old_aPtr = a.ptr;

   a ~= e;
   if (a.ptr != old_aPtr) {
     // Elements are moved; adjust the slice
     assert(b.ptr >= old_aPtr);
     const old_bOffset = b.ptr - old_aPtr;
     b = a[old_bOffset .. $];
   }

If you ask why I don't keep offsets instead of slices to begin with, I 
want to use pointers (implicitly in D slices) so that they participate 
in the ownership of array elements so that the GC does not free earlier 
elements as the buffer is popFronted as well.


More information about the Digitalmars-d mailing list