Skip to content

Commit 74aa7db

Browse files
committed
Fixing ASCII graphs and tightening up some wording
1 parent dfd4bdf commit 74aa7db

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

_posts/2025-04-27-undefined-behavior-vs-expected-behavior.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ In memory, it would look something like this:
362362
```bash
363363
Memory:
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

368368
Result:
369369
- Full 8 bytes cleared to 0
@@ -403,8 +403,8 @@ In memory, it would look something like this:
403403
```bash
404404
Memory:
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

409409
Result:
410410
- First 4 bytes (float f) zeroed.
@@ -494,8 +494,10 @@ mov [rax], rcx # copy full 8 bytes
494494

495495
Essentially, 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

500502
For 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

507509
So 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

513515
The latest change in GCC's handling of this breaks what I consider to be
514516
historical 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
529531
the 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).
531533
There'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

Comments
 (0)