Когда базовый класс может иметь макет, отличный от соответствующего полного типа объекта?

GCC и Clang не выполняют гарантированное копирование С++ 17 при вызове конструктора базового класса; см. этот вопрос и соответствующий отчет об ошибке Clang для деталей.

В ответ на сообщение об ошибке Ричард Смит заявляет:

Это дефект в стандартной редакции. Исключение копирования не может быть гарантировано при инициализации подобъекта базового класса, поскольку базовые классы могут иметь разную компоновку, чем соответствующий полный тип объекта.

При каких обстоятельствах базовый класс может иметь "макет, отличный от соответствующего полного типа объекта" таким образом, что делает невозможным гарантированное копирование? Есть конкретный пример, который иллюстрирует это?

Ответ 1

Всякий раз, когда виртуальное наследование вовлечено.

Пример:

struct A {
   int a;
   A (int a) : a(a) {}
};

struct B:  virtual A {
   B() : A(0) {}
};


B makeB { return B(); }

struct C : B {
  C() : B(makeB()), A(42) {}
};

Конструктор C инициализирует подобъект A, поэтому конструктор B не может. Как бы makeB узнал, должен ли он инициализировать A?

Удаление копии все еще теоретически возможно в этом случае. Реализация должна была бы прозрачно создать две двоичные версии makeB или добавить невидимый аргумент для makeB (т. makeB Использовать технику, применяемую для самих конструкторов), чтобы она могла создать B с инициализацией A или без нее. Однако это может потребовать несовместимых изменений в ABI.

Там может быть или не быть дефект в стандарте. Эта ситуация, вероятно, не была предусмотрена комитетом. Если бы это было так, я был бы рад прочитать обсуждение, так как оно, несомненно, оставило бумажный след. Так что намерение неясно, пока нет разъяснений от комитета. Если намерение состоит в том, чтобы в этом случае исключить возможность копирования, проклятие несовместимости ABI может потребовать дальнейших изменений в стандарте (если только комитет не предвидел ситуацию и не удостоверился, что все совместимо с ней, и в этом случае должны быть некоторые опять бумажный след).