Note that there are some explanatory texts on larger screens.

plurals
  1. POAliasing array with pointer-to-struct without violating the standard
    primarykey
    data
    text
    <p>Reading <a href="http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html" rel="nofollow">this</a> I understood that you can alias structures (without violating the standard, that is) if they have compatible members, i.e given the following struct:</p> <pre><code>typedef struct { uint32_t a; uint32_t b; } Frizzly; </code></pre> <p>The following would break aliasing rules:</p> <pre><code>uint32_t foo(uint16_t *i) { Frizzly *f = (Frizzly *)i; return f-&gt;a; } </code></pre> <p>But the following would not:</p> <pre><code>uint32_t foo(uint32_t *i) { Frizzly *f = (Frizzly *)i; return f-&gt;b; } </code></pre> <p>because the "aggregrate type" in question contains types compatible with the pointer that that we're casting into it, i.e. a pointer to type <code>uint32_t</code> can be casted into a struct that contains members (or a member) of type <code>uint32_t</code> without breaking aliasing rules.</p> <p>First, did I understand this correctly?</p> <p>Secondly, does the ordering and types of the (other) variables within the struct matter? Say, if <code>Frizzly</code> was defined as follows:</p> <pre><code>typedef struct { uint16_t b[2]; uint32_t a; } </code></pre> <p>After the cast in the second example, <code>b</code> is now backed by memory of incompatible (<code>uint32_t</code>) type. Is the cast still valid (or rather, accessing the values through the casted pointer)? Will changes to either element of <code>a</code> alter the value of first element of <code>i</code> (and the other way around) as though strict aliasing were disabled?</p> <p>Also, if the above is valid, what if I had a struct like so:</p> <pre><code>typedef struct { void *m; uint16_t hooah[4]; } Bar; </code></pre> <p>The following cast would, if I'm correct, break aliasing rules:</p> <pre><code>void test(char *boo, size_t dee) { Bar *bar = (Bar *)(boo + dee); do_other_stuff(bar); } </code></pre> <p>Could I make the cast valid simply by adding a single <code>unsigned char</code> member into the struct? In other words, casting pointers of incompatible types generally breaks aliasing rules, but since a cast from a pointer to a struct containing a member of type <code>X</code> into a pointer to <code>X</code> is an exception, can any cast from pointer-to-X to aggregrate-Y made valid simply by adding a (possibly dummy) member of type X into Y? </p> <p>(I didn't actually test the above code snippets in a compiler.)</p> <p><strong>EDIT:</strong></p> <p>I know my wording and examples might be rather poor, so I'll try to rephrase the question: if I understood correctly, it is legal for a pointer-to-struct to alias an array of elements of type 'X' as long as the struct contains members of type 'X'. Now, when dereferencing a member of the struct, does the member have to be of the type 'X', or are exceptions to the strict aliasing rules made for <em>all</em> members of the struct regardless of their types as long as there is one member of the appropriate type?</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.
 

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