Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The standard is fairly specific that even a POD-struct (which is, I believe the most restrictive class of structs) can have padding between members. ("There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment." -- a non-normative note, but still makes the intent quite clear).</p> <p>For example, contrast the requirements for a standard-layout struct (C++11, §1.8/4): </p> <blockquote> <p>An object of trivially copyable or standard-layout type (3.9) shall occupy contiguous bytes of storage."</p> </blockquote> <p>...with those for an array (§8.3.4/1):</p> <blockquote> <p>An object of array type contains a contiguously allocated non-empty set of N subobjects of type T.</p> </blockquote> <p>In the array, the <em>elements</em> themselves are required to be allocated contiguously, whereas in the struct, only the <em>storage</em> is required to be contiguous.</p> <p>The third possibility that might make the "contiguous storage" requirement make more sense would be to consider a struct/class that is not trivially copyable or standard layout. In this case, it's possible that the storage might might not be contiguous at all. For example, an implementation might set aside one area of memory for holding all the private variables, and an entirely separate area of memory to hold all the public variables. To make that a little more concrete, consider two definitions like:</p> <pre><code>class A { int a; public: int b; } a; class B { int x; public: int y; } b; </code></pre> <p>With these definitions, the memory might be laid out something like:</p> <pre><code>a.a; b.x; // ... somewhere else in memory entirely: a.b; b.y; </code></pre> <p>In this case, neither the elements <em>nor</em> the storage needs to be contiguous, so interleaving parts of entirely separate structs/classes is allowable. </p> <p>That said, the first element must be at the same address as the struct as a whole (9.2/17): "A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa."</p> <p>In your case, you have a POD-struct, so (§9.2/17): "A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa." Since the first member <em>must</em> be aligned, and the remaining members are all of the same type, it's impossible for any padding to be truly necessary between the other members (i.e., except for bit-fields, any type you can put in a struct you can also put in an array, where contiguous allocation of the elements is required). If you have elements smaller than a word, on a word-oriented machine (e.g., early DEC Alphas), it's possible that padding could make access somewhat simpler though. For example, early DEC Alphas (at the hardware level) were only capable of reading/writing an entirely (64-bit) word at a time. As such, let's consider something like a struct of four <code>char</code> elements:</p> <pre><code>struct foo { char a, b, c, d; }; </code></pre> <p>If it was required to lay these out in memory so they were contiguous, accessing a <code>foo::b</code> (for example) would require that the CPU load the word, then shift it 8-bits right, then mask to zero-extend that byte to fill the entire register.</p> <p>Storing would be even worse -- the CPU would have to load the current value of the whole word, mask out the current contents of the appropriate char-sized piece of that, shift the new value to the correct place, OR it into the word, and finally store the result.</p> <p>By contrast, with padding between the elements, each of those becomes a simple load/store, with no shifting, masking, etc.</p> <p>At least if memory serves, with DEC's normal compiler for the Alpha, <code>int</code> was 32 bits, and <code>long</code> was 64 bits (it predated <code>long long</code>). As such, with your struct of four <code>int</code>s, you could have expected to see another 32 bits of padding between the elements (and another 32 bits after the last element as well).</p> <p>Given that you do have a POD-struct, you still have some possibilities though. The one I'd probably prefer would be to use <code>offsetof</code> to get the offsets of the members of the struct, create an array of them, and access the members via those offsets. I showed how to do this in a <a href="https://stackoverflow.com/a/5088496/179910">couple</a> of <a href="https://stackoverflow.com/a/2043949/179910">previous answers</a>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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