Случайно "создает экземпляр" типа абстрактного класса, используя скобки-инициализаторы?

Сегодня я наткнулся на следующую проблему. Кто-то слишком любил инициализаторы скобок и случайно пытался создать интерфейс класса. Медведь со мной:

#include <iostream>

class IFoo
{
public:
   virtual ~IFoo() = default;
   virtual bool getFoo() const = 0;
};

void processFoo(const IFoo &fooImpl)
{
    bool foo = fooImpl.getFoo();
    std::cout << "got foo " << foo << std::endl;
}

int main()
{
   processFoo({});  // <- why is this valid?!
   return 0;
}

До сих пор я ожидал, что компилятор выпустит ошибку, подобную той, которую вы получаете, когда пытаетесь что-то глупо, как вызов IFoo() или IFoo{}. Однако приведенный выше код компилируется без предупреждения (на gcc 6.2), но, как только вы попытаетесь вызвать метод getFoo(), он, очевидно, завершится с помощью чистого виртуального метода, называемого. Пример в реальном времени.

Может кто-нибудь любезно объяснить мне, что там происходит?

Ответы

Ответ 1

Это известная ошибка GCC. К сожалению, проблема по-прежнему открыта и никому не назначена.