I am getting a warning (turned into an error with -Werror) about missing-field-initializers when using designated initializers for the fields in my struct, because I'm not initializing fields in a 3rd party base class, boost::intrusive::unordered_set_base_hook
error: missing initializer for member ‘foo::boost::intrusive::unordered_set_base_hook<>’
[-Werror=missing-field-initializers]
10 | foo f { .bar = 1 };
| ^
Here is a minimal reproducible example:
#include <boost/intrusive/unordered_set.hpp>
struct foo : boost::intrusive::unordered_set_base_hook<>
{
int bar;
};
int main()
{
foo f { .bar = 1 };
return 0;
}
Here is my CMakeLists.txt file. I am specifying that the boost include dir is a SYSTEM directory, to suppress warnings from boost headers.
cmake_minimum_required(VERSION 3.18)
project(scratch_test)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Boost)
add_executable(scratch
main.cpp
)
target_compile_options(scratch
PRIVATE
-Wmissing-field-initializers
-Werror
)
target_include_directories(scratch
SYSTEM PRIVATE
${Boost_INCLUDE_DIRS}
)
Looking at the source code for boost::intrusive, in effect the code effectively looks like this:
struct generic_hook
{
void* next_;
};
struct unordered_set_base_hook : generic_hook
{
};
So indeed next_ is not initialized.
I even tried to modify my code to use my own base class, which I in-class initialize to nullptr:
struct generic_hook
{
void* next_ {nullptr};
};
struct unordered_set_base_hook : generic_hook
{
};
struct foo : unordered_set_base_hook
{
int bar;
};
int main()
{
foo f { .bar = 1 };
return 0;
}
I still get the error:
error: missing initializer for member ‘foo::unordered_set_base_hook’
[-Werror=missing-field-initializers]
17 | foo f { .bar = 1 };
| ^
Is this a legitimate warning/error?
I do not really want to be responsible for initializing 3rd party dependency base class members; what is the correct course of action here?
Foo{ .bar = 1 }. It's missing an initializer for the base class field,missing-field-initializersis wider thanmissing-designated-field-initializers.missing-designated-field-initializersthat is also enabled by-Wmissing-field-initializerswhen you use designated initializers, and Clang only checks if non-static data members are initialized: github.com/llvm/llvm-project/blob/… (field_iterator only iterates over non-static data members), so skips over base classes. Maybe it is a GCC bug, but GCC is warning about a subobject without an explicit initializer// This matches gcc behaviour.