I'm writing some code using pimpl idiom with unique_ptr. When I tried to use in-class initialization to set unique_ptr to nullptr by default, gcc gave a compile error, while clang and msvc both successfully compiled the code. And if I didn't use in-class initialization the error went away.
// A.h
#pragma once
#include <memory>
using namespace std;
class B;
class A
{
private:
////////////////////////
// here gives the error!
////////////////////////
unique_ptr<B> impl{nullptr}; // error only with gcc,
// ok with clang and msvc
unique_ptr<B> impl2; // ok with all three
public:
A();
~A();
};
// A.cpp
#include "A.h"
class B
{
private:
int b{5};
public:
B() = default;
~B() = default;
};
A::A() = default;
A::~A() = default;
// main.cpp
#include "A.h"
int main()
{
A a;
return 0;
}
When I compiled the above code, gcc complained "error: invalid application of ‘sizeof’ to incomplete type ‘B’". I've tried both gcc 8.3 and gcc 9.1 with no success. Is this a compiler bug? Thanks!
Edit: I tried as @eerorika suggested. If the header and source files are merged into one single file, it can compile normally, but not separated.
Edit Confirmed to be compiler bug and already fixed in gcc9.2.
The program, and the default member initialiser in particular, is well-formed. If a compiler refuses to compile, then it is a bug in the compiler as far as I can tell.
I can reproduce the problem with GCC 9.1 but not 9.2 nor trunk, so it appears to have been fixed. With older versions, you may need to give up using the default member initialiser as a workaround.