Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

missing-field-initializers warning for 3rd party dependency base class

Tags:

c++

gcc

boost

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?

like image 740
Steve Lorimer Avatar asked Nov 02 '25 22:11

Steve Lorimer


1 Answers

The error is not about void* next_ being uninitialized, but about you not providing an explicit initializer for something in your class. This warning is meant to warn you if you accidentally forget that a base class or data member exists when initializing, most useful for cases like:

struct Foo {
    int x;
    int y;
    int z;
};

Foo f{ .x = 1, .z = 2 };  // Forgot to provide an initializer for y, should write .y = 0 or .y = {}.

There's currently no way to use designated intializers with base classes, so you would have to write:

int main()
{
    foo f { boost::intrusive::unordered_set_base_hook<>(), 1 };
    // Or
    foo f { {}, 1 };
    return 0;
}

Aggregate initialization is kind of a pain in general if there are base classes, I would recommend just writing a constructor if you want to keep the error. Or use -Wno-error=missing-field-initializers to downgrade to a warning or -Wno-missing-field-initializers to silence completely.

like image 117
Artyer Avatar answered Nov 05 '25 12:11

Artyer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!