Ошибка компиляции Clang с инициализацией по умолчанию

Рассмотрим следующий пример:

#include <iostream>
#include <type_traits>

struct A
{
  //A() = default; // does neither compile with, nor without this line
  //A(){};         // does compile with this line
  int someVal{ 123 };


  void foobar( int )
  {
  };
};


int main()
{
    const A a;
    std::cout << "isPOD = " << std::is_pod<A>::value << std::endl;
    std::cout << "a.someVal = " <<a.someVal << std::endl;
}

Смотреть живой пример

Это компилируется с помощью g++, но не компилируется с clang++, пробовал с помощью следующей команды: clang++ -std=c++11 -O0 main.cpp && ./a.out

Ошибка компиляции от clang:

main.cpp: 19: 13: ошибка: для инициализации по умолчанию объекта константного типа «const A» требуется предоставленный пользователем конструктор по умолчанию

Я узнал из этого переполнения стека Вопрос, классы, не относящиеся к POD, получают конструктор по умолчанию. Здесь это даже не нужно, потому что переменная имеет инициализацию по умолчанию в стиле С++ 11.

Почему это не для clang? Почему A() = default; тоже не работает?


person meddle0106    schedule 05.02.2015    source источник


Ответы (2)


Вы сами процитировали ответ. В ответе SO, который вы связали, есть следующая цитата из стандарта (точно раздел 6.8.6):

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

акцент мой. Линия

A() = default;

очевидно, не предоставляет конструктор, он делает обратное, сообщая компилятору, что вы не хотите его предоставлять, поэтому ваш код не компилируется. Однако, как только вы предоставите конструктор, раскомментировав

 A(){}; 

это работает нормально. Итак, подведем итог: ошибка, которую показывает clang, соответствует стандарту, а поведение gcc, вероятно, является ошибкой.

person SingerOfTheFall    schedule 05.02.2015

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

Цитирование части связанной проблемы

Примечания к встрече в августе 2011 г.:

Если неявный конструктор по умолчанию инициализирует все подобъекты, инициализатор не требуется.

Технически это активная проблема, но, учитывая это примечание, кажется вероятным, что она будет решена тем способом, который gcc выбрал для ее реализации.

Clang, с другой стороны, подождал, пока проблема не будет решена, прежде чем реализация решения.

В Clang мы ждем, пока проблема действительно будет решена, прежде чем принять решение по ней.

Итак, в нынешнем виде clang является правильным.

person Praetorian    schedule 05.02.2015
comment
Я думаю, что эту тему следует закрыть как дубликат предложения Ремябеля; возможно, также опубликуйте свой ответ в этой теме - person M.M; 05.02.2015
comment
Ответ @MattMcNabb Potatoswatter в другой ветке более полный, чем мой, поэтому я не хочу добавлять к этому шум. - person Praetorian; 05.02.2015