<div dir="ltr">I posted this to std-discussion, but I figured I might get more response from the undefined-behavior list instead.<br><div><br><br>The C++ Standard permits you to use <span style="font-family:monospace,monospace">offsetof()</span> on standard-layout 
classes, but does it permit using that offset in pointer arithmetic with
 object pointers that have been <span style="font-family:monospace,monospace">reinterpret_cast</span> to [<span style="font-family:monospace,monospace">unsigned</span>] <span style="font-family:monospace,monospace">char *</span>?<br><br>The
 section on pointer arithmetic is predicated on &quot;if the pointer object 
points to an element of an array object&quot; (§5.7/4), with undefined 
behavior otherwise.  It has a footnote stating that, &quot;an object that is 
not an array is considered to belong to a single-element array for this 
purpose&quot;.  But if you <span style="font-family:monospace,monospace">reinterpret_cast</span> a pointer to a single object into
 a <span style="font-family:monospace,monospace">char</span> pointer, that&#39;s not a pointer to an array object.<br><br>Does 
this mean that doing pointer arithmetic on a <span style="font-family:monospace,monospace">reinterpret_cast</span> <span style="font-family:monospace,monospace">char</span> 
pointer of a single object in order to reach other members is undefined 
behavior even for standard-layout types?  It seems to me that this was 
not the intention of the Standard.  Getting around this would require 
using <span style="font-family:monospace,monospace">memcpy</span> into a <span style="font-family:monospace,monospace">char</span> array, only ever using the offset for indexing 
into that <span style="font-family:monospace,monospace">char</span> array, then copying back.<br><br>Another possible 
interpretation of the Standard is that the <span style="font-family:monospace,monospace">reinterpret_cast</span> pointer 
*does* point to an array.  One way this interpretation could be derived 
is from §1.8/5: &quot;An object of trivially copyable or standard-layout type
 (3.9) shall occupy contiguous bytes of storage.&quot;.<br><br><br><div style="background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><span style="color:rgb(136,0,0)">#include</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,136,0)">&lt;cmath&gt;</span><span style="color:rgb(0,0,0)"><br></span><span style="color:rgb(136,0,0)">#include</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,136,0)">&lt;cstdio&gt;</span><span style="color:rgb(0,0,0)"><br></span><span style="color:rgb(136,0,0)">#include</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,136,0)">&lt;cstdlib&gt;</span><span style="color:rgb(0,0,0)"><br></span><span style="color:rgb(136,0,0)">#include</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,136,0)">&lt;cstring&gt;</span><span style="color:rgb(0,0,0)"><br></span><span style="color:rgb(136,0,0)">#include</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,136,0)">&lt;type_traits&gt;</span><span style="color:rgb(0,0,0)"><br><br></span><span style="color:rgb(0,0,136)">struct</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(102,0,102)">Meow</span><span style="color:rgb(0,0,0)"><br></span><span style="color:rgb(102,102,0)">{</span><span style="color:rgb(0,0,0)"><br>    </span><span style="color:rgb(0,0,136)">int</span><span style="color:rgb(0,0,0)"> x</span><span style="color:rgb(102,102,0)">;</span><span style="color:rgb(0,0,0)"><br>    </span><span style="color:rgb(0,0,136)">float</span><span style="color:rgb(0,0,0)"> y</span><span style="color:rgb(102,102,0)">;</span><span style="color:rgb(0,0,0)"><br></span><span style="color:rgb(102,102,0)">};</span><span style="color:rgb(0,0,0)"><br><br></span><span style="color:rgb(0,0,136)">int</span><span style="color:rgb(0,0,0)"> main</span><span style="color:rgb(102,102,0)">()</span><span style="color:rgb(0,0,0)"><br></span><span style="color:rgb(102,102,0)">{</span><span style="color:rgb(0,0,0)"><br>    </span><span style="color:rgb(102,0,102)">Meow</span><span style="color:rgb(0,0,0)"> meow</span><span style="color:rgb(102,102,0)">;</span><span style="color:rgb(0,0,0)"><br>    </span><span style="color:rgb(0,0,136)">static_assert</span><span style="color:rgb(102,102,0)">(</span><span style="color:rgb(0,0,0)">std</span><span style="color:rgb(102,102,0)">::</span><span style="color:rgb(0,0,0)">is_standard_layout</span><span style="color:rgb(102,102,0)">&lt;</span><span style="color:rgb(102,0,102)">Meow</span><span style="color:rgb(102,102,0)">&gt;::</span><span style="color:rgb(0,0,0)">value</span><span style="color:rgb(102,102,0)">,</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,136,0)">&quot;Meow isn&#39;t standard-layout&quot;</span><span style="color:rgb(102,102,0)">);</span><span style="color:rgb(0,0,0)"><br><br>    </span><span style="color:rgb(136,0,0)">// Aliasing rules allow this (3.10/8)</span><span style="color:rgb(0,0,0)"><br>    </span><span style="color:rgb(0,0,136)">unsigned</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,0,136)">char</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(102,102,0)">*</span><span style="color:rgb(0,0,0)">p </span><span style="color:rgb(102,102,0)">=</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,0,136)">reinterpret_cast</span><span style="color:rgb(102,102,0)">&lt;</span><span style="color:rgb(0,0,136)">unsigned</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,0,136)">char</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(102,102,0)">*&gt;(&amp;</span><span style="color:rgb(0,0,0)">meow</span><span style="color:rgb(102,102,0)">);</span><span style="color:rgb(0,0,0)"><br><br>    </span><span style="color:rgb(136,0,0)">// Meow is standard-layout, but is this technically undefined behavior?</span><span style="color:rgb(0,0,0)"><br>    p </span><span style="color:rgb(102,102,0)">+=</span><span style="color:rgb(0,0,0)"> offsetof</span><span style="color:rgb(102,102,0)">(</span><span style="color:rgb(102,0,102)">Meow</span><span style="color:rgb(102,102,0)">,</span><span style="color:rgb(0,0,0)"> y</span><span style="color:rgb(102,102,0)">);</span><span style="color:rgb(0,0,0)"><br><br>    </span><span style="color:rgb(0,0,136)">float</span><span style="color:rgb(0,0,0)"> z </span><span style="color:rgb(102,102,0)">=</span><span style="color:rgb(0,0,0)"> std</span><span style="color:rgb(102,102,0)">::</span><span style="color:rgb(0,0,0)">exp</span><span style="color:rgb(102,102,0)">(</span><span style="color:rgb(0,102,102)">1.0f</span><span style="color:rgb(102,102,0)">);</span><span style="color:rgb(0,0,0)"><br>    std</span><span style="color:rgb(102,102,0)">::</span><span style="color:rgb(0,0,0)">memcpy</span><span style="color:rgb(102,102,0)">(</span><span style="color:rgb(0,0,0)">p</span><span style="color:rgb(102,102,0)">,</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(102,102,0)">&amp;</span><span style="color:rgb(0,0,0)">z</span><span style="color:rgb(102,102,0)">,</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,0,136)">sizeof</span><span style="color:rgb(102,102,0)">(</span><span style="color:rgb(0,0,136)">float</span><span style="color:rgb(102,102,0)">));</span><span style="color:rgb(0,0,0)"><br>    <br>    std</span><span style="color:rgb(102,102,0)">::</span><span style="color:rgb(0,0,0)">printf</span><span style="color:rgb(102,102,0)">(</span><span style="color:rgb(0,136,0)">&quot;%f\n&quot;</span><span style="color:rgb(102,102,0)">,</span><span style="color:rgb(0,0,0)"> meow</span><span style="color:rgb(102,102,0)">.</span><span style="color:rgb(0,0,0)">y</span><span style="color:rgb(102,102,0)">);</span><span style="color:rgb(0,0,0)"><br><br>    </span><span style="color:rgb(0,0,136)">return</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,102,102)">0</span><span style="color:rgb(102,102,0)">;</span><span style="color:rgb(0,0,0)"><br></span><span style="color:rgb(102,102,0)">}</span><span style="color:rgb(0,0,0)"><br></span></div></code></div><br></div><div><br></div><div>Addendum to my original email: For this to be undefined would be to invalidate decades of existing programming practice.<br></div><div><br></div><div>Melissa<br></div></div>