Ошибка компиляции с gcc при инициализации в классе unique_ptr неполного типа в nullptr - PullRequest
3 голосов
/ 14 октября 2019

Я пишу некоторый код, используя идиому pimpl с unique_ptr. Когда я попытался использовать инициализацию в классе, чтобы по умолчанию установить unique_ptr в nullptr, gcc выдал ошибку компиляции, в то время как clang и msvc оба успешно скомпилировали код. И если я не использовал инициализацию в классе, ошибка исчезла.

// 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;
}

Когда я скомпилировал приведенный выше код, gcc пожаловался: «ошибка: неверное применение« sizeof »длянеполный тип 'B' ". Я пробовал оба gcc 8.3 и gcc 9.1 безуспешно. Это ошибка компилятора? Спасибо!

Редактировать: Я пытался, как подсказал @eerorika. Если заголовочные и исходные файлы объединены в один файл, он может нормально скомпилироваться, но не разделяться.

Редактировать Подтверждено, что это ошибка компилятора, и уже исправлено в gcc9.2.

1 Ответ

4 голосов
/ 14 октября 2019

Программа и, в частности, инициализатор элемента по умолчанию, хорошо сформированы. Если компилятор отказывается от компиляции, то, насколько я могу судить, это ошибка компилятора.

Я могу воспроизвести проблему с GCC 9.1, но не с 9.2 или транком, поэтому, похоже, она была исправлена. В старых версиях может потребоваться отказаться от использования инициализатора элемента по умолчанию в качестве обходного пути.

...