On Fri, May 02, 2025 at 03:05:34AM +0100, Al Viro wrote:
On Thu, May 01, 2025 at 06:24:49PM -0700, Nathan Chancellor wrote:
How long has that been valid? Because this is certainly new to the kernel, and sparse does complain about this initializer.
As you noted, brace initialization for scalars appears to always be valid (at least in my testing) but as Al points out, empty braces for scalars is only supported in GCC 13+ and Clang 17+ (I think [1] was the clang commit), so that is not going to fly...
From some digging around it looks like
- {} for compounds had been an extension for quite a while
- C++11 got it into standard, with semantics defined as "same
value you get for static-duration variables of that type without an explicit initializer". For scalar types as well, with the same semantics.
- On C side that happened (again, with scalar types allowed)
in 2022; N2912 is the first draft with that change already merged, N2913 is the corresponding editor's report, saying that change in question (N2900) got merged in January/February virtual meeting. IOW, C23 has it, no previous versions do. For C17 this syntax is an error, and AFAICS you need at least -std=c2x or -std=gnu2x to have it acceptable.
Neat, thanks for digging around.
We can make sparse accept it (either unconditionally or with sufficient -std in arguments), but that won't do a damn thing for cc(1). Does clang (any version) really accept it with -std=gnu11?
Yes, it appears that both GCC and clang accept it even with -std=gnu89: https://godbolt.org/z/GYKrKhTdf
The clang commit mentions that this is exposed to older C modes like the GNU extension was.
I guess another option to locally silence the warning would be to insert something like
#if defined(__clang__) && __clang_major__ >= 21 #define typecheck_init = {} #else #define typecheck_init #endif
#define typecheck(type,x) \ ({ type __dummy typecheck_init; \ typeof(x) __dummy2 typecheck_init; \ (void)(&__dummy == &__dummy2); \ 1; \ })
but maybe that is just too ugly or worthless.
Cheers, Nathan