title: Does the pointer arithmetic in this usage cause undefined behavior
body: <p>This is a follow up to the <a href="https://stackoverflow.com/questions/67416686/serializing-structure-which-includes-pointers">following question</a>. I was under the assumption, that the pointer arithmetic I originally used would cause undefined behavior. However I was told by a colleague, that the usage is actually well defined. The following is a simplified example:</p>
  <pre class="lang-cpp prettyprint-override"><code>typedef struct StructA {
      int a;
  } StructA ;
  
  typedef struct StructB {
      StructA a;
      StructA* b;
  } StructB;
  
  int main() {
      StructB* original = (StructB*)malloc(sizeof(StructB));
      original-&gt;a.a = 5;
      original-&gt;b = &amp;original-&gt;a;
  
      StructB* copy = (StructB*)malloc(sizeof(StructB));
      memcpy(copy, original, sizeof(StructB));
      free(original);
      ptrdiff_t offset = (char*)copy - (char*)original;
      StructA* a = (StructA*)((char*)(copy-&gt;b) + offset);
      printf(&quot;%i\n&quot;, a-&gt;a);
      free(copy)
  }
  </code></pre>
  <p>According to §5.7 ¶5 of the C++11 spec:</p>
  <blockquote>
  <p>If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.</p>
  </blockquote>
  <p>I assumed, that the following part of the code:</p>
  <pre class="lang-cpp prettyprint-override"><code>ptrdiff_t offset = (char*)copy - (char*)original;
  StructA* a = (StructA*)((char*)(copy-&gt;b) + offset);
  </code></pre>
  <p>causes undefined behavior, since it:</p>
  <ol>
  <li>subtracts two pointers, which point to different arrays</li>
  <li>the resulting pointer of the offset calculation does not point into the same array anymore.</li>
  </ol>
  <p>Does this cause undefined behavior, or do I misinterpret the C++ specification? Does the same apply in C as well?</p>
  <h2>Edit:</h2>
  <p>Following the comments I assume the following modification would still be undefined behavior because of the object usage after the lifetime has ended:</p>
  <pre class="lang-cpp prettyprint-override"><code>ptrdiff_t offset = (char*)(copy-&gt;b) - (char*)original;
  StructA* a = (StructA*)((char*)copy + offset);
  </code></pre>
  <p>Would it be defined when working with indexes instead:</p>
  <pre class="lang-cpp prettyprint-override"><code>typedef struct StructB {
      StructA a;
      ptrdiff_t b_offset;
  } StructB;
  
  int main() {
      StructB* original = (StructB*)malloc(sizeof(StructB));
      original-&gt;a.a = 5;
      original-&gt;b_offset = (char*)&amp;(original-&gt;a) -  (char*)original
  
      StructB* copy = (StructB*)malloc(sizeof(StructB));
      memcpy(copy, original, sizeof(StructB));
      free(original);
      StructA* a = (StructA*)((char*)copy + copy-&gt;b_offset);
      printf(&quot;%i\n&quot;, a-&gt;a);
      free(copy);
  }
  </code></pre>