Вопрос по value-initialization
От: rg45 СССР  
Дата: 16.05.17 00:26
Оценка:
Всем привет.

struct A
{
  int* p;
  std::string s;
};

int main()
{
  A a = A();
  std::cout << a.p << std::endl;
}


Смотрю стандарт (C++14, 8.5) и не могу взять в толк, можно ли в этом примере рассчитывать на то, что a.p будет zero-initialized?

Опытным путем установил, что поведение компиляторов, поддерживающих C++11 и выше, отличается от поведения компиляторов более ранних версий.
--
Re: Вопрос по value-initialization
От: jazzer Россия Skype: enerjazzer
Дата: 16.05.17 02:11
Оценка: +1
Здравствуйте, rg45, Вы писали:

R>Смотрю стандарт (C++14, 8.5) и не могу взять в толк, можно ли в этом примере рассчитывать на то, что a.p будет zero-initialized?


Да. А что смущает?

R>Опытным путем установил, что поведение компиляторов, поддерживающих C++11 и выше, отличается от поведения компиляторов более ранних версий.


Это, вроде, ещё в С++03 разрулили.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Вопрос по value-initialization
От: rumit7  
Дата: 16.05.17 05:37
Оценка: +1 -1
Здравствуйте, jazzer, Вы писали:

J>Это, вроде, ещё в С++03 разрулили.


в с++03 вроде нужно было в конструкторе явно инициализировать pod-типы типа такого:

struct A
{
  A() : p() {}

  int* p;
  std::string s;
};
Re: Вопрос по value-initialization
От: rumit7  
Дата: 16.05.17 06:52
Оценка: 28 (2)
Здравствуйте, rg45, Вы писали:

R>Всем привет.


R>
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
Re: Вопрос по value-initialization
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 16.05.17 07:05
Оценка: +5
Здравствуйте, 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;


и это просто полезно с точки зрения читаемости — лучше не перейматься, а вписать все инициализации явно и забыть о проблеме.
The God is real, unless declared integer.
Re[2]: Вопрос по value-initialization
От: N. I.  
Дата: 16.05.17 07:39
Оценка: 14 (1) +1
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 сливаются в один).
Отредактировано 16.05.2017 7:47 N. I. . Предыдущая версия .
Re[3]: Вопрос по value-initialization
От: jazzer Россия Skype: enerjazzer
Дата: 16.05.17 07:50
Оценка: 6 (1)
Здравствуйте, rumit7, Вы писали:

R>Здравствуйте, jazzer, Вы писали:


J>>Это, вроде, ещё в С++03 разрулили.


R>в с++03 вроде нужно было в конструкторе явно инициализировать pod-типы типа такого:


R>
R>struct A
R>{
R>  A() : p() {}

R>  int* p;
R>  std::string s;
R>};
R>


Нет. Именно в С++03 и разделили default initialization и value initialization, это главная фишка С++03 была.
Вот в С++98 — да, надо было явно выписывать.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Вопрос по value-initialization
От: rg45 СССР  
Дата: 16.05.17 07:58
Оценка: +1 :)
Здравствуйте, jazzer, Вы писали:

J>Нет. Именно в С++03 и разделили default initialization и value initialization, это главная фишка С++03 была.

J>Вот в С++98 — да, надо было явно выписывать.

Но я точно помню, что msvc-9.0 лажал на этом, и приходилось искать обходные пути. Выходило так, что класс не является POD-м, поскольку содержит нестатические члены — не POD-ы. И конструктрор, сгенерированный компилятором не инициализоровал члены POD-ы, даже если полный объект создавался при помощи value-initialization.
--
Отредактировано 16.05.2017 8:04 rg45 . Предыдущая версия . Еще …
Отредактировано 16.05.2017 8:03 rg45 . Предыдущая версия .
Re[5]: Вопрос по value-initialization
От: jazzer Россия Skype: enerjazzer
Дата: 16.05.17 08:08
Оценка:
Здравствуйте, 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 (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: Вопрос по value-initialization
От: rg45 СССР  
Дата: 16.05.17 08:10
Оценка:
Здравствуйте, jazzer, Вы писали:

R>>Но я точно помню, что msvc-9.0 лажал на этом, и приходилось искать обходные пути. Выходило так, что класс не является POD-м, поскольку содержит нестатические члены — не POD-ы. И конструктрор, сгенерированный компилятором не инициализоровал члены POD-ы, даже если полный объект создавался при помощи value-initialization.


J>При чем тут POD? Она в разделе про value initialization вообще не упоминается​.


Значит, я не очень удачно сформулировал вопрос. В разделе хоть и не упоминается, но меня интересует именно этот случай.
--
Отредактировано 16.05.2017 8:11 rg45 . Предыдущая версия .
Re[6]: Вопрос по value-initialization
От: rumit7  
Дата: 16.05.17 08:12
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Ну а то, что msvc всегда затейливо поддерживал стандарт, думаю, ни для кого не секрет.

J>Именно для таких художеств в бусте есть value_initialized.

тут вроде гцц
Отредактировано 16.05.2017 8:12 rumit7 . Предыдущая версия .
Re[7]: Вопрос по value-initialization
От: jazzer Россия Skype: enerjazzer
Дата: 16.05.17 08:12
Оценка:
Здравствуйте, rg45, Вы писали:

J>>При чем тут POD? Она в разделе про value initialization вообще не упоминается​.


R>Значит, я не очень удачно сформулировал вопрос. В разделе хоть и не упоминается, но меня интересует именно этот случай.


Какой? Сорри, я не понимаю, чего ты от нас хочешь

Не упоминается — значит, не зависит.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[7]: Вопрос по value-initialization
От: jazzer Россия Skype: enerjazzer
Дата: 16.05.17 08:17
Оценка: 6 (1)
Здравствуйте, rumit7, Вы писали:

R>Здравствуйте, jazzer, Вы писали:


J>>Ну а то, что msvc всегда затейливо поддерживал стандарт, думаю, ни для кого не секрет.

J>>Именно для таких художеств в бусте есть value_initialized.

R>тут вроде гцц


C++: g++ 4.1.2
flags: -O -std=c++98

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[8]: Вопрос по value-initialization
От: rg45 СССР  
Дата: 16.05.17 08:23
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Какой? Сорри, я не понимаю, чего ты от нас хочешь


Хорошо, перезагружаемся. Ниже видоизмененный пример, показывающий разное поведение двух разных версий gcc — в одном случае член инициализируется, в другом — нет. Если сравним msvc-9.0 и msvc-14.0, увидим ту же картину. Я хочу, чтобы мне объяснили причины этого разного поведения.

gcc 4.3.2
gcc C++14

#include <iostream>
#include <string>

struct Base
{
  int* p;
  std::string s;
};

struct A : Base
{
  A() : Base() { }
};

int main()
{
  A a;
  std::cout << a.p << std::endl;
}
--
Отредактировано 16.05.2017 8:34 rg45 . Предыдущая версия .
Re[9]: Вопрос по value-initialization
От: jazzer Россия Skype: enerjazzer
Дата: 16.05.17 08:34
Оценка: 21 (2)
Здравствуйте, rg45, Вы писали:

R>Хорошо, перезагружаемся. Ниже видоизмененный пример, показывающий разное поведение двух разных версий gcc — в одном случае член инициализируется, в другом — нет. Я хочу, чтобы мне объяснили причины этого разного поведения.


R>gcc 4.3.2


GCC bug 30111, fixed in 4.4.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Вопрос по value-initialization
От: N. I.  
Дата: 16.05.17 08:46
Оценка: 38 (3) +1 :)))
rg45:

R>Но я точно помню, что msvc-9.0 лажал на этом


Там, похоже, и в самых новых версиях value-initialization не пофиксили. Я попробовал скормить вот такой код

#include <cassert>

struct A
{
    int *p;
    int *A::*pm;
};

int main()
{
    A a = A();
    assert(a.p == nullptr);
    assert(a.pm == nullptr);
}

онлайн-компилятору http://webcompiler.cloudapp.net/ [на данный момент там MSVC v19.10.25206.0 (x86)] — второй assert фэйлится
Re[2]: Вопрос по value-initialization
От: rg45 СССР  
Дата: 16.05.17 09:22
Оценка:
Здравствуйте, 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?? Эдакая супер-пупер инициализация. А где в стандарте то место, которое описывает такое поведение, не подскажешь?
--
Re[3]: Вопрос по value-initialization
От: rumit7  
Дата: 16.05.17 09:39
Оценка:
Здравствуйте, 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

Re[3]: Вопрос по value-initialization
От: jazzer Россия Skype: enerjazzer
Дата: 16.05.17 09:39
Оценка:
Здравствуйте, rg45, Вы писали:

R>Это ж трындец какой-то, извините за мой француский Выходит, что value-initialization класса B, исправляет "недоработки" конструктора класса A?? Эдакая супер-пупер инициализация. А где в стандарте то место, которое описывает такое поведение, не подскажешь


8.5/8(8.2)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: Вопрос по value-initialization
От: _NN_ www.nemerleweb.com
Дата: 16.05.17 19:54
Оценка:
Здравствуйте, N. I., Вы писали:

NI>rg45:


R>>Но я точно помню, что msvc-9.0 лажал на этом


NI>Там, похоже, и в самых новых версиях value-initialization не пофиксили. Я попробовал скормить вот такой код

По сравнению с MSVC-9.0 первая строка не падает.
Вот он прогресс за 9 лет

Закинул в Connect.
Насколько я заметил в 2017-й компиляторе баги стали править намного быстрее, глядишь через месяц-другой выйдет исправления версия.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.