Compile error with gcc when in-class initializing unique_ptr of incomplete type to nullptr
Asked Answered
A

1

3

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.

Apeman answered 14/10, 2019 at 11:34 Comment(4)
Compiles file here (GCC 9.2.1). But fails as you describe with GCC 8, so likely a bug that's since been fixed.Repay
As the initialization is superfluous, then use the simpler form that works and less verbose.Brigandine
(...) but not separated. Have you tried, in A.h define the destructor, i.e. ~A() = default;?Vermin
@Vermin That would definitely result in compile error, see #9955018 . This has been confirmed to be a compiler bug and fixed. See eerorika's answer for detailsApeman
A
5

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.

Audio answered 14/10, 2019 at 11:43 Comment(2)
Thanks for your help but I'm not sure about the result. You merged the 3 files into one, I tried the same on my computer and it did compiled, but if I separate them to header and source files as I originally did and the error came back.Apeman
@X.Sun fair enough; it does seem to reproduce. Separating the TU's is not simple on the online tools unfortunately.Audio

© 2022 - 2024 — McMap. All rights reserved.