←back to thread

GCC 15.1

(gcc.gnu.org)
272 points jrepinc | 1 comments | | HN request time: 0.208s | source
Show context
Calavar ◴[] No.43792948[source]
> {0} initializer in C or C++ for unions no longer guarantees clearing of the whole union (except for static storage duration initialization), it just initializes the first union member to zero. If initialization of the whole union including padding bits is desirable, use {} (valid in C23 or C++) or use -fzero-init-padding-bits=unions option to restore old GCC behavior.

This is going to silently break so much existing code, especially union based type punning in C code. {0} used to guarantee full zeroing and {} did not, and step by step we've flipped the situation to the reverse. The only sensible thing, in terms of not breaking old code, would be to have both {0} and {} zero initialize the whole union.

I'm sure this change was discussed in depth on the mailing list, but it's absolutely mind boggling to me

replies(14): >>43793036 #>>43793080 #>>43793121 #>>43793150 #>>43793166 #>>43794045 #>>43794558 #>>43796460 #>>43798312 #>>43798826 #>>43800132 #>>43800234 #>>43800932 #>>43800975 #
ogoffart ◴[] No.43793121[source]
> This is going to silently break so much existing code

The code was already broken. It was an undefined behavior.

That's a problem with C and it's undefined behavior minefields.

replies(3): >>43793132 #>>43793486 #>>43796042 #
ryao ◴[] No.43793132[source]
GCC has long been known to define undefined behavior in C unions. In particular, type punning in unions is undefined behavior under the C and C++ standards, but GCC (and Clang) define it.
replies(3): >>43793225 #>>43793908 #>>43794163 #
flohofwoe ◴[] No.43794163[source]
> type punning in unions is undefined behavior under the C and C++ standards

Union type punning is entirely valid in C, but UB in C++ (one of the surprisingly many subtle but still fundamental differences between C and C++). There's specifically a (somewhat obscure) footnote about this in the C standard, which also has been more clarified in one of the recent C standards.

replies(1): >>43794351 #
ryao ◴[] No.43794351[source]
There is no footnote about it in the C standard. Someone proposed adding one to standardize the behavior, but it was never accepted. Ever since then, people keep quoting it even though it is a rejected amendment.
replies(1): >>43794374 #
jcranmer ◴[] No.43794374[source]
Footnote 107 in C23, on page 75 in §6.5.2.3:

> If the member used to read the contents of a union object is not the same as the member last used to store a value in the object the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called type punning). This might be a non-value representation.

(though this footnote has been present as far back as C99, albeit with different numbers as the standard has added more text in the intervening 24 years).

replies(1): >>43794415 #
ryao ◴[] No.43794415[source]
The GCC developers disagree with your interpretation:

> Type punning via unions is undefined behavior in both c and c++.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118141#c13

replies(2): >>43794552 #>>43804876 #
1. nialv7 ◴[] No.43804876[source]
I wouldn't be surprised if Andrew Pinski was just wrong. It's anecdotal but my impression of him isn't very good.