3 ms·
There are two additional ways of making this work. The first is to allocate the memory using char a[sizeof(float)]. In C, char pointers may alias anything, so
by ryao 2y ago
There are two additional ways of making this work.
The first is to allocate the memory using char a[sizeof(float)]. In C, char pointers may alias anything, so then you can do pointer conversions that would normally be undefined behavior and it should work. The other option is to use the non-standard __attribute__((__may_alias__)) on the pointer.
By the way, using union types for this is technically undefined behavior in the C and C++ standards, but GCC and Clang decided to make it defined as an implementation choice. Other compilers might not.
- gpderetta 2y agoThe union trick is actually defined in C. And note that while char can alias anything, the reverse is not true: i.e. you can't generally cast a char array to anything else and expect sensible behaviour. There are ways to make this work (placement new in C++ for example), but it is not a way to escape TBAA: if you store a float in char array you can't then cast it to int with impunity.
- atiedebee 2y agoTo be more precise, it is defined since c99[0]. In c89 it was undefined, but type punning is the most used/sensible behaviour, so they changed it in c99. [0]: https://en.cppreference.com/w/c/language/union https://en.cppreference.com/w/c/language/union
- gpderetta 2y agoYes, it 2025, I thought that we could at least imply C99 when talking about plain C :). I'm probably an optimist.
- ryao 2y agoIt does not matter. The C99 standard does not define this behavior: https://news.ycombinator.com/item?id=42568271m https://news.ycombinator.com/item?id=42568271m
- ryao 2y agoThat is a common misconception. DR 283 is a suggestion for an amendment that was filed 3 years after C99 was published: https://open-std.org/jtc1/sc22/wg14/www/docs/dr_283.htm https://open-std.org/jtc1/sc22/wg14/www/docs/dr_283.htm It is not part of C99. It also is not part of the C standard since no subsequent C standard adopted it according to the GCC developers: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118141#c13 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118141#c13 A read of the C11 standard draft, which would have this amendment if it were accepted by the C standards committee, shows that this has not been added: https://open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf https://open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf Type punning via union types is therefore undefined behavior unless your compiler implements an extension to define it like GCC and Clang do.
- atiedebee 2y agoOh that's interesting. I guess I should actually look at the standard instead of taking cppreference's word for it next time
- gpderetta 2y agoHum, from your wg14 link: 6.5.2.3 comma 3 and note 95. I thought that was the note that was added on TC3. Also the note is non-normative, so it is only clarifying preexisting behaviour. But I'm far from an expert on the C standard. Also that was the C11 draft, maybe the note was removed before the final standard. Edit: I believe the alias rules are in 6.5 comma 7; specifically: > An object shall have its stored value accessed only by an lvalue expression that has one of the following types: [...] >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), Edit2: neither commas nor the note have changed in the 202y Draft.
- deleted 2y ago[deleted]
- deleted 2y ago[deleted]
- 2y ago