@@ -362,8 +362,8 @@ In memory, it would look something like this:
362362``` bash
363363Memory:
364364[00][00][00][00][00][00][00][00]
365- ^^^^^^^^ first 4 bytes = float f
366- ^^^^^^^^^^^^^ rest 4 bytes = padding / start of double d
365+ ^^^^^^ ^^^^^^^^ first 4 bytes = float f
366+ ^ ^^^^^^^^^^^^^ rest 4 bytes = padding / start of double d
367367
368368Result:
369369- Full 8 bytes cleared to 0
@@ -403,8 +403,8 @@ In memory, it would look something like this:
403403``` bash
404404Memory:
405405[00][00][00][00][?? ][?? ][?? ][?? ]
406- ^^^^^^^^ first 4 bytes = float f
407- ^^^^^^^^^^^^^ remaining 4 bytes = untouched
406+ ^^^^^^ ^^^^^^^^ first 4 bytes = float f
407+ ^ ^^^^^^^^^^^^^ remaining 4 bytes = untouched
408408
409409Result:
410410- First 4 bytes (float f) zeroed.
@@ -494,8 +494,10 @@ mov [rax], rcx # copy full 8 bytes
494494
495495Essentially, Clang is zero'ing the 4 byte float, but then it goes ahead and
496496` memset ` 's the rest of the union resulting in behavior similar to the older
497- versions of GCC. It is almost as if the two compiler teams switched opinions on
498- how this should be implemented!
497+ versions of GCC. I am guessing this is to make sure the entire memory region
498+ is zeroed out. TO me, it is almost as if the two compiler teams switched
499+ opinions on how this should be implemented with GCC now only clearing the first
500+ member, and Clang now clearing out the entire region.
499501
500502For anyone who wants to verify this, I created some godbolt links.
501503
@@ -505,10 +507,10 @@ For anyone who wants to verify this, I created some godbolt links.
505507## Where GCC Breaks Historical Behavior
506508
507509So here is where we get to the main point of the issue. For over a decade, C
508- devs have expected ` {0} ` to fully clear unions. Type punning is allowed in the
509- newer C standards, and compilers have gone to great lengths to try to maintain
510- memory safety by adhering to expected behavior, even if it is undefined or
511- unspecified.
510+ devs have expected ` {0} ` to fully clear unions. Type punning appears to be
511+ allowed, at least to some degree, in the newer C standards, and compilers have
512+ gone to great lengths to try to maintain memory safety by adhering to expected
513+ behavior, even if it is undefined or unspecified.
512514
513515The latest change in GCC's handling of this breaks what I consider to be
514516historical behavior, and it might lead to some interesting bugs that begin to
@@ -529,11 +531,13 @@ I completely understand why the GNU GCC team is allowed to do this given how
529531the spec reads. Many GCC devs claim that
530532[ type punning via unions is undefined] ( https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118141#c13 ) .
531533There's also no such thing as truly historical behavior in the spec. However,
532- there are certain things programmers rely on to be valid, even if they aren't
533- well-defined. This is one of those cases where I think the compiler team might
534- want to re-evaluate their decision, or at the very least present a solid
535- argument as to why they are breaking away from a historical behavior that many
536- of us have come to rely on, even if it was considered UB.
534+ there are certain assumptions programmers rely on to be valid, for better or
535+ for worse, even if they aren't well-defined. I really do believe this is one of
536+ those cases where I think the compiler team might want to re-evaluate their
537+ decision on making this flag-defined behavior instead of default behavior, or
538+ at the very least present a solid argument as to why they are shifting away
539+ from a historical behavior that many of us have come to rely on, even if it
540+ was considered UB.
537541
538542## Further Reading
539543
0 commit comments