1

Given an union like:

union {
  uint16_t halfwords[32];
  uint32_t fullwords[16];
} my_union;

what does the Strict Aliasing rule say about e.g.

my_union.fullwords[0] = 1;
printf("%d", my_union.halfwords[1]);

For purposes of the Strict Aliasing Rule, is my_union.halfwords[1] considered to be a legitimate access to part of a union, or is it considered to take an address which happens to point just past the first element of halfwords, and then perform an illegitimate uint16_t read of that address (which a compiler could then accept as an invitation to do whatever it wants).

It would seem semantically like any sane compiler would have all the information needed to recognize it as being a member of the union, but is there anything in the Standard that would require a compiler to do so?

If it's necessary to pass one of the arrays or a portion thereof to another function, would it still be possible to access the other array via the Union?

If it's necessary to pass one of the arrays to one method, and the other to another method, is there any efficient action which can be performed between those actions to ensure that the compiler doesn't think strict aliasing is violated?

supercat
  • 77,689
  • 9
  • 166
  • 211
  • Possibly a duplicate of [this](http://stackoverflow.com/questions/11373203/accessing-inactive-union-member-undefined-behavior)? – Lundin Oct 13 '15 at 06:56
  • @Lundin: That looks like C++, isn't it? – supercat Oct 13 '15 at 07:47
  • The accepted answer shows how "type punning" through unions is allowed in C but forbidden in C++. I believe the quoted part from 6.5.2.3 should be what applies to your question. – Lundin Oct 13 '15 at 09:03

1 Answers1

2

Thats indeed allowed. In C the C11 Standart explicitly permits type-punning.

If you want to have a better read on this, see here

Ps: Dont upvote this, I posted this just for visibilitys sake and the content of this is not my own thought to answer, but a summary of what I read in the link provided.

Edit: I found this explaination, which looks like roughly what you are looking for. It at least implies that you can write directly to the array through the union.

Community
  • 1
  • 1
Magisch
  • 7,312
  • 9
  • 36
  • 52
  • Type punning is clearly permitted in a union which contains things of primitive types. I don't see anything, though, that makes clear in what cases writing to an array which is a member of a union is considered to be a write through the union. – supercat Oct 13 '15 at 07:47
  • I found this here: http://stackoverflow.com/questions/1812348/a-question-about-union-in-c – Magisch Oct 13 '15 at 07:49
  • That one uses an array of "char", and a single larger primitive. In the example I give above, there are two arrays and neither of them would be able to exploit the special rules about "char". – supercat Oct 13 '15 at 08:01
  • 1
    @supercat, 6.5.2.3 explicitly allows to read from another member that had been written. The only problem that that text identifies are possible trap representations. Since the `uintXX_t` types don't have traps, this is not a problem, here. – Jens Gustedt Oct 13 '15 at 08:48
  • @supercat Regarding whether it applies to arrays inside unions, I think the actual "strict aliasing rule" itself addresses that, (6.5/7): "an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union)". That section of the standard is very hard to read though, which is why I refrain from posting an answer myself. – Lundin Oct 13 '15 at 09:07
  • @JensGustedt: According to the Standard, `arrayLValue[x]` is equivalent to `*(arrayLValue+x)`, but neither clang nor gcc will recognize that an access to `*(someUnion.intArray+i)` may interact with an access to `*(someUnion.shortArray+j)` even if the same union object is used for both accesses. – supercat Mar 18 '19 at 20:39