Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You can compare the assembly generated for basic functions (I used GCC 4.8.1 on OS X 10.7.4)</p> <pre><code>struct Point3D { float m_data[3]; }; struct Point3Ds { float x; float y; float z; }; double dot(const Point3D&amp; p1, const Point3D&amp; p2) { asm("# Dot - Point3D"); return p1.m_data[0] * p2.m_data[0] + p1.m_data[1] * p2.m_data[1] + p1.m_data[2] * p2.m_data[2]; } double dot(const Point3Ds&amp; p1, const Point3Ds&amp;p2) { asm("# Dot - Point3Ds"); return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z; } Point3D cross(const Point3D&amp; p1, const Point3D&amp; p2) { asm("# Cross - Point3D"); return { p1.m_data[1] * p2.m_data[2] - p1.m_data[2] * p2.m_data[1], p1.m_data[2] * p2.m_data[0] - p1.m_data[0] * p2.m_data[2], p1.m_data[0] * p2.m_data[1] - p1.m_data[1] * p2.m_data[0]}; } Point3D cross(const Point3Ds&amp; p1, const Point3Ds&amp; p2) { asm("# Cross - Point3Ds"); return { p1.y * p2.z - p1.z * p2.y, p1.z * p2.x - p1.x * p2.z, p1.x * p2.y - p1.y * p2.x}; } </code></pre> <p>Compiling as <code>g++ -O3 -S</code> I obtain the following assembler (relevant parts):</p> <pre><code># 12 "point3f.cpp" 1 # Dot - Point3D # 0 "" 2 movss (%rdi), %xmm0 movss 4(%rdi), %xmm1 mulss (%rsi), %xmm0 mulss 4(%rsi), %xmm1 addss %xmm1, %xmm0 movss 8(%rdi), %xmm1 mulss 8(%rsi), %xmm1 addss %xmm1, %xmm0 unpcklps %xmm0, %xmm0 cvtps2pd %xmm0, %xmm0 ret LFE0: .align 4,0x90 .globl __Z3dotRK8Point3DsS1_ __Z3dotRK8Point3DsS1_: LFB1: # 19 "point3f.cpp" 1 # Dot - Point3Ds # 0 "" 2 movss (%rdi), %xmm0 movss 4(%rdi), %xmm1 mulss (%rsi), %xmm0 mulss 4(%rsi), %xmm1 addss %xmm1, %xmm0 movss 8(%rdi), %xmm1 mulss 8(%rsi), %xmm1 addss %xmm1, %xmm0 unpcklps %xmm0, %xmm0 cvtps2pd %xmm0, %xmm0 ret LFE1: .align 4,0x90 .globl __Z5crossRK7Point3DS1_ __Z5crossRK7Point3DS1_: LFB2: # 26 "point3f.cpp" 1 # Cross - Point3D # 0 "" 2 movss 4(%rdi), %xmm3 movss 8(%rdi), %xmm1 movss 8(%rsi), %xmm5 movaps %xmm3, %xmm2 movss 4(%rsi), %xmm4 movaps %xmm1, %xmm0 mulss %xmm5, %xmm2 mulss %xmm4, %xmm0 subss %xmm0, %xmm2 movss (%rdi), %xmm0 mulss %xmm0, %xmm5 movss %xmm2, -24(%rsp) movss (%rsi), %xmm2 mulss %xmm4, %xmm0 mulss %xmm2, %xmm1 mulss %xmm3, %xmm2 subss %xmm5, %xmm1 subss %xmm2, %xmm0 movss %xmm1, -20(%rsp) movss %xmm0, -16(%rsp) movq -24(%rsp), %xmm0 movd -16(%rsp), %xmm1 ret LFE2: .align 4,0x90 .globl __Z5crossRK8Point3DsS1_ __Z5crossRK8Point3DsS1_: LFB3: # 33 "point3f.cpp" 1 # Cross - Point3Ds # 0 "" 2 movss 4(%rdi), %xmm3 movss 8(%rdi), %xmm1 movss 8(%rsi), %xmm5 movaps %xmm3, %xmm2 movss 4(%rsi), %xmm4 movaps %xmm1, %xmm0 mulss %xmm5, %xmm2 mulss %xmm4, %xmm0 subss %xmm0, %xmm2 movss (%rdi), %xmm0 mulss %xmm0, %xmm5 movss %xmm2, -24(%rsp) movss (%rsi), %xmm2 mulss %xmm4, %xmm0 mulss %xmm2, %xmm1 mulss %xmm3, %xmm2 subss %xmm5, %xmm1 subss %xmm2, %xmm0 movss %xmm1, -20(%rsp) movss %xmm0, -16(%rsp) movq -24(%rsp), %xmm0 movd -16(%rsp), %xmm1 ret </code></pre> <p>So the assembly is identical. But I agree that it would be more practical to store as an static array (that is, a <code>float m_data[3]</code>) because I can have the best of both worlds: a single parameter to pass when I need to, and a high-level, idiomatic <code>x</code>, <code>y</code>, <code>z</code> via getters. In that sense, I believe I would implement such class in a manner similar to:</p> <pre><code>class MyPoint3S { public: MyPoint3S(float x, float y, float z) : m_data{x, y, z} { } // the following getters will be inlined float x() const { return m_data[0]; } float y() const { return m_data[1]; } float z() const { return m_data[2]; } // in case you want to use the pointer --- some would advice against // offering a hook to a private member. float* data() { return m_data; } private: float m_data[3]; }; </code></pre> <p>And use it like:</p> <pre><code>MyPoint3S p(1.0f, 2.0f, 3.0f); std::cout&lt;&lt;"p = "&lt;&lt;p.x()&lt;&lt;", "&lt;&lt;p.y()&lt;&lt;", "&lt;&lt;p.z()&lt;&lt;std::endl; </code></pre> <p>to obtain:</p> <pre><code>p = 1, 2, 3 </code></pre> <p>Or call OpenGL functions in whatever way you prefer:</p> <pre><code>glVertex3fv(p.data()); </code></pre> <p>or</p> <pre><code>glVertex3f(p.x(), p.y(), p.z()); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload