Union { 0 } initializer is no longer clean in GCC 15
GCC: https://gcc.gnu.org/gcc-15/changes.html:
{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=unionsoption to restore old GCC behavior.
This is critical for WASMValue whose first member is int32_t, but obviously it has larger members.
Discussions: https://news.ycombinator.com/item?id=43792948
I think if this were true, we do need to add -fzero-init-padding-bits=unions for newer versions of GCC. I am pretty shocked like people in the discussion.
I think if this were true, we do need to add -fzero-init-padding-bits=unions for newer versions of GCC.
as mentioned in the referenced discussion, it isn't only gcc. clang didn't have the extension until recently. https://github.com/llvm/llvm-project/pull/97121 i suspect it's simpler for us to use memset.
I will check the union {} initializer. I think we can replace them if there are not too many
I will check the union {} initializer. I think we can replace them if there are not too many
is it ok for us to require c23?
If embedded platforms' compilers are compatible with C23.
If embedded platforms' compilers are compatible with C23.
i suspect we can't assume they are at this point.
As far as I know, C23 is the default mode starting with GCC 15. GCC 15 is the default version beginning with Ubuntu 25.04. This means that typically, Ubuntu 22.04 (one of CI platforms) and 24.04 won't support C23 unless GCC 15 is installed manually. Therefore, I believe this issue won't affect us in the near future.
embedded targets sometimes require vendor-provided toolchain, which might be based on older gcc.
I prefer not using C23 and only addressing this problem when encountering GCC 15 or higher.
I prefer not using C23 and only addressing this problem when encountering GCC 15 or higher.
sure. it means not using {}, right? what do we recommend to use instead? memset?
IIUC, this problem only occurs when using GCC 15 or higher. Currently, WAMR's major development and CI environment is still Ubuntu 22.04, and its default GCC version is GCC 11, which still uses traditional zero-initialization, so there's generally no need to worry about the problem. If that's the case, we only need to add -fzero-init-padding-bits=unions when using GCC 15 or higher.
IIUC, this problem only occurs when using GCC 15 or higher. Currently, WAMR's major development and CI environment is still Ubuntu 22.04, and its default GCC version is GCC 11, which still uses traditional zero-initialization, so there's generally no need to worry about the problem. If that's the case, we only need to add
-fzero-init-padding-bits=unionswhen using GCC 15 or higher.
for GCC 15, sure. however, the problem exists with old clang before https://github.com/llvm/llvm-project/pull/97121. besides that, the problem might exists with other compilers. after all, it's allowed by the C standard.
😓 other compilers ...
Since it only changes the expectation for unions and most of their usage in WAMR is for structs and arrays, which are not affected, using memset is one approach. Alternatively, we maybe could adjust the definition and keep the longest one in the first member?