Use of empty tag struct, compiler claims I'm missing initializer, except I'm not

Okay, I know this is similar to this Why is the compiler throwing this warning: "missing initializer"? Isn't the structure initialized?, but surely GCC isn't stupid enough to think I meant to initialize something which has NO initialization?.

//main.cpp
struct IsNamed{
};

template<typename T>
struct Test{
    int foo;
};
struct Test2 : public Test<double>, public IsNamed{

};
int main(){
    Test2 x;

    Test2 y = Test2{Test<double>{}};
    return 0;
}

Here's the output:

main2.cpp: In function 'int main()':
main2.cpp:18:35: warning: missing initializer for member 'Test2::<anonymous>' [-Wmissing-field-initializers]
   18 |     Test2 y = Test2{Test<double>{}};
      |                                   ^
main2.cpp:16:11: warning: unused variable 'x' [-Wunused-variable]
   16 |     Test2 x;
      |           ^
main2.cpp:18:11: warning: variable 'y' set but not used [-Wunused-but-set-variable]
   18 |     Test2 y = Test2{Test<double>{}};
      |    

The only warning I'm confused about is this " missing initializer for member 'Test2:: " warning. It makes no sense. There's only one possible value I would need, and I provide it. Just to prove that it is indeed the inclusion of the empty class in the inheritance chain that is causing this, here's the output if I remove it:

main2.cpp: In function 'int main()':
main2.cpp:16:11: warning: unused variable 'x' [-Wunused-variable]
   16 |     Test2 x;
      |           ^
main2.cpp:18:11: warning: variable 'y' set but not used [-Wunused-but-set-variable]
   18 |     Test2 y = Test2{Test<double>{}};
      |  

People say just ignore it, but it's not feasible for my project. I've got lots of classes with this error that follow the same tag struct pattern. It's not reasonable to selectively disable this warning (I also find it useful in other circumstances).

How do I get the compiler to stop complaining about this? I should also mention that Test2{Test<double>{},{}}; would not be an appropriate solution, as I have template code in use where some of the classes do not have this problem, and some do, which means this becomes an error in those circumstances.

EDIT:

Note here is the example CMake used, which included the compiler options:

cmake_minimum_required(VERSION 3.13)
project(test)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)

add_executable(test main.cpp)
target_include_directories(test
        PRIVATE
        ./
        )
target_compile_options(test PRIVATE
        $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
        -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -g -ggdb -O1>)

I'm also using mingw64-10.2

1 answer

  • answered 2021-01-26 07:35 eerorika

    There's only one possible value I would need, and I provide it

    The warning isn't about providing values that you "need". After all, the compiler cannot in general know which values you think are needed.

    The warning is about providing all initialisers. And there is no initialiser for the other base.

    How do I get the compiler to stop complaining about this?

    Provide the missing initialiser:

    Test2 y = Test2{Test<double>{}, {}};
    

    Or just disable the warning. Or use another compiler; Clang appears to not warn in your case for example.