Подтвердить что ты не робот

Почему gcc разрешает объект const без объявленного пользователем конструктора по умолчанию, но не clang?

Недавно Почему объект const требует, чтобы пользовательский конструктор по умолчанию? был отмечен дубликат Почему С++ требует созданный по умолчанию конструктор по умолчанию для построения объекта const?. Я использую coliru и rextexter, чтобы проверить различные версии gcc (g++ - 4.7, g++ - 4.8, g++ - 4.9) и clang (3.4 и 3.5), чтобы узнать, было ли это поведение введено в новых версиях компилятора. Здесь у нас есть два тестовых примера, взятых из обоих вопросов:

class A {
public:
    void f() {}

};

int main()
{
    A a;       // OK
    const A b; // ERROR

    a.f();
    return 0;
}

и

struct B{
  B():x(42){}
  int doSomeStuff() const{return x;}
  int x;
};

struct A{
  A(){}//other than "because the standard says so", why is this line required?

  B b;//not required for this example, just to illustrate
      //how this situation isn't totally useless
};

int main(){
  const A a;
}

ошибки clang:

 error: default initialization of an object of const type 'const A' requires a user-provided default constructor
  A const a;
          ^

ожидается, но не gcc, и MSVC также не работает. Я думал, что, возможно, я схожу с ума, потому что в стандартных цитатах ясно сказано:

§ 8.5

6 Для инициализации объекта типа T по умолчанию:

- если T является (возможно, cv-квалифицированным) классом типа (раздел 9), конструктор по умолчанию для T называется (и инициализация плохо сформирована, если T не имеет доступный конструктор по умолчанию);

[...]

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

11 Если для объекта не задан инициализатор, объект по умолчанию инициализируется; [...]

Язык, не содержащий POD, присутствующий во втором вопросе, кажется, отсутствует в n3337, поэтому, возможно, мне не хватает чего-то, что могло измениться. Это ошибка, дубликат или я что-то упускаю?

4b9b3361

Ответ 1

В настоящее время спецификация требует пользовательских конструкторов по умолчанию, но похоже, что GCC реализует изменение, основанное на DR 253, в котором говорится, что если все суб -объекты будут инициализированы без предоставленного пользователем конструктора по умолчанию, тогда предоставленный пользователем конструктор по умолчанию не требуется.

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

Здесь приведено изменение первого примера, из-за которого GCC создает ошибку:

class A {
public:
    void f() {}

    int i;
};

int main()
{
    A a;       // OK
    const A b; // ERROR

    a.f();
    return 0;
}

Обратите внимание, что gcc понижает ошибку до предупреждения с помощью флага -fpermissive.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42844