Здравствуйте, rg45, Вы писали:
R>Смотрю стандарт (C++14, 8.5) и не могу взять в толк, можно ли в этом примере рассчитывать на то, что a.p будет zero-initialized?
Да. А что смущает?
R>Опытным путем установил, что поведение компиляторов, поддерживающих C++11 и выше, отличается от поведения компиляторов более ранних версий.
R>struct A
R>{
R> int* p;
R> std::string s;
R>};
R>int main()
R>{
R> A a = A();
R> std::cout << a.p << std::endl;
R>}
R>
R>Смотрю стандарт (C++14, 8.5) и не могу взять в толк, можно ли в этом примере рассчитывать на то, что a.p будет zero-initialized?
R>Опытным путем установил, что поведение компиляторов, поддерживающих C++11 и выше, отличается от поведения компиляторов более ранних версий.
Разве пример приведенный здесь не описывает Ваш случай?
struct A
{
int i;
A() { } // user-provided default ctor, does not initialize i
};
struct B { A a; }; // implicitly-defined default ctor
std::cout << B().a.i << '\n'; // value-initializes a B temporary// leaves b.a.i uninitialized in C++03// sets b.a.i to zero in C++11
Здравствуйте, rg45, Вы писали:
R>Всем привет.
R>struct A R>{ R> int* p; R> std::string s; R>};
R>Смотрю стандарт (C++14, 8.5) и не могу взять в толк, можно ли в этом примере рассчитывать на то, что a.p будет zero-initialized?
Вообще, так как с C++11 можно писать
int *p = nullptr;
и это просто полезно с точки зрения читаемости — лучше не перейматься, а вписать все инициализации явно и забыть о проблеме.
rumit7:
R>Разве пример приведенный здесь не описывает Ваш случай?
R>
R>struct A
R>{
R> int i;
R> A() { } // user-provided default ctor, does not initialize i
R>};
В его случае у A нет user-declared или user-provided конструкторов. Начиная с C++03 (где понятие value-initialization впервые появилось), p должно быть проиницилизировано соответствующим нулевым значением:
To value-initialize an object of type T means:
....
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
К non-static data member p применяется
To value-initialize an object of type T means:
....
— otherwise, the object is zero-initialized
и дальше
To zero-initialize an object of type T means:
— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
Нулевое значение будет либо скопировано из A().p в a.p копирующим конструктором A, либо присвоено a.p непосредственно за счёт value-initialization (если произошло copy elision, из-за которого объекты A() и a сливаются в один).
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, jazzer, Вы писали:
J>>Это, вроде, ещё в С++03 разрулили.
R>в с++03 вроде нужно было в конструкторе явно инициализировать pod-типы типа такого:
R>
Нет. Именно в С++03 и разделили default initialization и value initialization, это главная фишка С++03 была.
Вот в С++98 — да, надо было явно выписывать.
Здравствуйте, jazzer, Вы писали:
J>Нет. Именно в С++03 и разделили default initialization и value initialization, это главная фишка С++03 была. J>Вот в С++98 — да, надо было явно выписывать.
Но я точно помню, что msvc-9.0 лажал на этом, и приходилось искать обходные пути. Выходило так, что класс не является POD-м, поскольку содержит нестатические члены — не POD-ы. И конструктрор, сгенерированный компилятором не инициализоровал члены POD-ы, даже если полный объект создавался при помощи value-initialization.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, jazzer, Вы писали:
J>>Нет. Именно в С++03 и разделили default initialization и value initialization, это главная фишка С++03 была. J>>Вот в С++98 — да, надо было явно выписывать.
R>Но я точно помню, что msvc-9.0 лажал на этом, и приходилось искать обходные пути. Выходило так, что класс не является POD-м, поскольку содержит нестатические члены — не POD-ы. И конструктрор, сгенерированный компилятором не инициализоровал члены POD-ы, даже если полный объект создавался при помощи value-initialization.
При чем тут POD? Она в разделе про value initialization вообще не упоминается.
Ну а то, что msvc всегда затейливо поддерживал стандарт, думаю, ни для кого не секрет.
Именно для таких художеств в бусте есть value_initialized.
Здравствуйте, jazzer, Вы писали:
R>>Но я точно помню, что msvc-9.0 лажал на этом, и приходилось искать обходные пути. Выходило так, что класс не является POD-м, поскольку содержит нестатические члены — не POD-ы. И конструктрор, сгенерированный компилятором не инициализоровал члены POD-ы, даже если полный объект создавался при помощи value-initialization.
J>При чем тут POD? Она в разделе про value initialization вообще не упоминается.
Значит, я не очень удачно сформулировал вопрос. В разделе хоть и не упоминается, но меня интересует именно этот случай.
Здравствуйте, jazzer, Вы писали:
J>Ну а то, что msvc всегда затейливо поддерживал стандарт, думаю, ни для кого не секрет. J>Именно для таких художеств в бусте есть value_initialized.
Здравствуйте, rg45, Вы писали:
J>>При чем тут POD? Она в разделе про value initialization вообще не упоминается.
R>Значит, я не очень удачно сформулировал вопрос. В разделе хоть и не упоминается, но меня интересует именно этот случай.
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, jazzer, Вы писали:
J>>Ну а то, что msvc всегда затейливо поддерживал стандарт, думаю, ни для кого не секрет. J>>Именно для таких художеств в бусте есть value_initialized.
R>тут вроде гцц
Здравствуйте, jazzer, Вы писали:
J>Какой? Сорри, я не понимаю, чего ты от нас хочешь
Хорошо, перезагружаемся. Ниже видоизмененный пример, показывающий разное поведение двух разных версий gcc — в одном случае член инициализируется, в другом — нет. Если сравним msvc-9.0 и msvc-14.0, увидим ту же картину. Я хочу, чтобы мне объяснили причины этого разного поведения.
Здравствуйте, rg45, Вы писали:
R>Хорошо, перезагружаемся. Ниже видоизмененный пример, показывающий разное поведение двух разных версий gcc — в одном случае член инициализируется, в другом — нет. Я хочу, чтобы мне объяснили причины этого разного поведения.
R>gcc 4.3.2
Здравствуйте, rumit7, Вы писали:
R>Разве пример приведенный здесь не описывает Ваш случай?
R>
R>struct A
R>{
R> int i;
R> A() { } // user-provided default ctor, does not initialize i
R>};
R>struct B { A a; }; // implicitly-defined default ctor
R>
std::cout << B().a.i << '\n'; // value-initializes a B temporary
// leaves b.a.i uninitialized in C++03
// sets b.a.i to zero in C++11
// (note that B{}.a.i leaves b.a.i uninitialized in C++11, but for
// a different reason: in post-DR1301 C++11, B{} is aggregate-initialization,
// which then value-initializes A, which has a user-provided ctor)
Это ж трындец какой-то, извините за мой француский Выходит, что value-initialization класса B, исправляет "недоработки" конструктора класса A?? Эдакая супер-пупер инициализация. А где в стандарте то место, которое описывает такое поведение, не подскажешь?
Здравствуйте, rg45, Вы писали:
R>Это ж трындец какой-то, извините за мой француский Выходит, что value-initialization класса B, исправляет "недоработки" конструктора класса A?? Эдакая супер-пупер инициализация. А где в стандарте то место, которое описывает такое поведение, не подскажешь?
с++11 (draft n3290):
7 To value-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the
default constructor for T is called (and the initialization is ill-formed if T has no accessible default
constructor);
— if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object
is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is
called.
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized.
Since C++11, value-initializing a class without a user-provided constructor, which has a member of a class type with a user-provided constructor zeroes out the member before calling its constructor
Здравствуйте, rg45, Вы писали:
R>Это ж трындец какой-то, извините за мой француский Выходит, что value-initialization класса B, исправляет "недоработки" конструктора класса A?? Эдакая супер-пупер инициализация. А где в стандарте то место, которое описывает такое поведение, не подскажешь
Здравствуйте, N. I., Вы писали:
NI>rg45:
R>>Но я точно помню, что msvc-9.0 лажал на этом
NI>Там, похоже, и в самых новых версиях value-initialization не пофиксили. Я попробовал скормить вот такой код
По сравнению с MSVC-9.0 первая строка не падает.
Вот он прогресс за 9 лет
Закинул в Connect.
Насколько я заметил в 2017-й компиляторе баги стали править намного быстрее, глядишь через месяц-другой выйдет исправления версия.