<div dir="ltr"><div class="gmail_default" style="color:rgb(0,51,0)"><div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><font color="#003300">I was investigating a difference in struct layout between clang and other compilers we use. We have many structs that inherit from an empty base struct ("Object"). The first member of these structs is usually at offset 0; but in clang, one of them has its first member at offset 4. </font><span style="color:rgb(0,51,0)">It turns out that this happens when that first member is also a subclass of Object.</span></div>
<div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><font color="#003300"><br></font></div><div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">
<font color="#003300">That led me to some language lawyer research into the EBO and standard layout rules of C++11; maybe not coincidentally, there is a new-ish standard layout rule which says "</font><span style="color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif;line-height:15.360000610351563px">6. has no base classes of the same type as the first non-static data member" (ref: </span><span style="color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif;line-height:15.360000610351563px"><a href="http://en.cppreference.com/w/cpp/types/is_standard_layout" target="_blank">http://en.cppreference.com/w/cpp/types/is_standard_layout</a>). Confusingly, not all C++11 reference sites quote that rule 6. Also confusingly, clang reports that my oddball struct is in fact "standard layout"</span></div>
<div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif;line-height:15.360000610351563px"><br>
</span></div><div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif;line-height:15.360000610351563px">My questions are:</span></div>
<div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif;line-height:15.360000610351563px">- Is it a bug that clang puts my struct's first member at offset 0?</span></div>
<div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif;line-height:15.360000610351563px">- Is it a bug that clang claims my struct __is_standard_layout()?</span></div>
<div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif;line-height:15.360000610351563px">- (Perhaps also: should I instead bring this up on cfe-dev?)</span></div>
<div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><br></div><div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><span style="line-height:15.360000610351563px;color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif">Thanks for any insight! My test case follows.</span><br>
</div><div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><span style="line-height:15.360000610351563px;color:rgb(0,0,0);font-family:DejaVuSans,'DejaVu Sans',arial,sans-serif">p</span></div>
<div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"><br>
</span></font></div><div class="gmail_default" style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">// Compiled with latest Xcode's clang, using</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">// clang foo.cc</span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">// clang -cc1 -fdump-record-layouts foo.cc</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">#define cassert(expr) typedef char failed[(expr)?1:-1]</span></font></div>
<div class="gmail_default">
<font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"><br></span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">class Object {};</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">struct RsaLight : public Object {</span></font></div><div class="gmail_default">
<font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> float data;</span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">};</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"><br></span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">struct Weather : public Object {</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> RsaLight m_first;</span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> float data;</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">};</span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"><br>
</span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">class Object2 {};</span></font></div><div class="gmail_default">
<font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">struct Weather2 : public Object2 {</span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> RsaLight m_first;</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> float data;</span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">};</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"><br></span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">int main(int argc, char** argv) {</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> // Q1: Should this assert actually fail?</span></font></div><div class="gmail_default">
<font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> cassert(__is_standard_layout(Weather));</span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> // Q2: Should this offsetof actually be 0?</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> cassert(__builtin_offsetof(Weather, m_first) == 4);</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"><br></span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> cassert(__is_standard_layout(Weather2));</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> cassert(__builtin_offsetof(Weather2, m_first) == 0);</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"><br></span></font></div><div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px"> return sizeof(Weather) + sizeof(Weather2);</span></font></div>
<div class="gmail_default"><font color="#000000" face="DejaVuSans, DejaVu Sans, arial, sans-serif"><span style="line-height:15.360000610351563px">}</span></font></div></div></div></div>