Welcome to LWN.net
The following subscription-only content has been made available to you
by an LWN subscriber. Thousands of subscribers depend on LWN for the
best news from the Linux and free software communities. If you enjoy this
article, please consider subscribing to LWN. Thank you
for visiting LWN.net!
By Jonathan Corbet
April 24, 2025
New compiler releases often bring with them new warnings; those warnings
are usually welcome, since they help developers find problems before they
turn into nasty bugs. Adapting to new warnings can also create disruption
in the development process, though, especially when an important developer
upgrades to a new compiler at an unfortunate time. This is just the
scenario that played out with the 6.15-rc3
kernel release and the implementation of
-Wunterminated-string-initialization
in GCC 15.
Consider a C declaration like:
char foo[8] = "bar";
The array will be initialized with the given string, including the normal
trailing NUL byte indicating the end of the string. Now consider this
variant:
char foo[8] = "NUL-free";
This is a legal declaration, even though the declared array now lacks the
room for the NUL byte. That byte will simply be omitted, creating an
unterminated string. That is often not what the developer who wrote that
code wants, and it can lead to unpleasant bugs that are not discovered
until some later time. The -Wunterminated-string-initialization
option emits a warning for this kind of initialization, with the result
that, hopefully, the problem — if there is a problem — is fixed quickly.
The kernel community has worked to make use of this warning and, hopefully,
eliminate a source of bugs. There is only one little problem with the new
warning, though: sometimes the no-NUL initialization is exactly what is
wanted and intended. See, for example, this
declaration from fs/cachefiles/key.c:
static const char cachefiles_charmap[64] = "0123456789" /* 0 - 9 */
8 Comments
jey
That the annotation applies to variables and not types is surely an oversight or mistake right? Seems like it could have been easier to initially implement that way but it just doesn’t seem to fit with how C type system works. (Yes it will make declarations uglier to do it on types but that ship has sailed long ago; see cdecl.org)
AceJohnny2
Fedora stupidly uses beta compiler in new release, Torvalds blindly upgrades, makes breaking, unreviewed changes in kernel, then flames the maintainer who was working on cleanly updating the kernel for the not-yet-released compiler?
I admire Kees Cook's patience.
jaapz
Torvalds is known for being flamey towards kernel maintainers, but most of the time that is for good reason. Here however, he should just admit he made a mistake instead of doubling down. Admitting your own mistakes is a mark of a great maintainer as well.
Ukv
From the comments:
> C "strings" work the way they do because C is a low level language, where you want to be able to do low-level things when necessary. It's a feature, not a deficiency.
Are NUL-terminated strings really considered preferable, even for low-level work? I always just considered them an unfortunate design choice C was stuck with.
Many O(1) operations/checks become O(n) because you have to linearly traverse the entire string (or keep a second pointer) to know where it ends/how long it is; you can't take a substring within another string without reallocating and copying that part over with a new NUL appended at the end; you can't store data that may contain a NUL (which text shouldn't, in theory, but then you need a separate approach for binary data); and plenty of security issues arise from missing or extra NULs.
Philpax
Linus was a hypocritical asshole here, but more to the point, why are they using strings for this anyway? No byte arrays / literals in their C dialect?
Incipient
This is definitely unexpected for me – I'd have thought something like an RC for a kernel would have to be 'approved' for release only after passing all tests, which should include building with all official compilers (and all official architectures, etc).
Unless either the older GCC or the beta GCC isn't "official"? In which case that's not necessarily expected to be picked up in an RC?
bjourne
Err… we teach C neophytes that you should never write values to variables that are larger than what the variables can hold. Don't write an int to a short, don't write a short to a char, and don't initialize five bytes to an array storing four bytes. Am I missing something here? char foo[4] = "ABCD" is always incorrect, no ifs and buts. If you want "readable" bytes, use character literals. You should never discount the null terminator.
mastax
It’s still shocking to me that there’s no official kernel CI.