Почему 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, поэтому, возможно, мне не хватает чего-то, что могло измениться. Это ошибка, дубликат или я что-то упускаю?
Ответы
Ответ 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