Обратите внимание std::vector
не делает проверки диапазона также.
Default constructor for POD types fills it with zeros. When you explicitly define your own constructor you are not initialize x
and y
and you'll get random values (in VS debug they are filled with exact values, but in release they will be random).
It is according to C++03 Standard 8.5/5:
<...>To value-initialize an object of type T means:
- если T является типом класса (пункт 9) с конструктором, объявленным пользователем (12.1), то вызывается конструктор по умолчанию для T (и инициализация плохо сформирована, если T не имеет доступного конструктора по умолчанию);
- если T является типом класса без объединения без конструктора, объявленного пользователем, то каждый нестатический член данных и компонент базового класса T инициализируется значением;
- если T является типом массива, то каждый элемент инициализируется значением;
- в противном случае объект инициализируется нулем .
B ()
- это временная инициализация значения, которая будет использоваться при инициализации копии b1
.
В B b2
не указан инициализатор для объекта, поэтому согласно стандарту C ++ 03 8.5 / 9:
Если для объекта не указан инициализатор , и объект имеет (возможно, cv-квалифицированный) тип класса, отличный от POD (или его массив), объект должен быть инициализирован по умолчанию; если объект имеет тип, определяемый константой, базовый тип класса должен иметь конструктор по умолчанию, объявленный пользователем. В противном случае, если для нестатического объекта не указан инициализатор, объект и его подобъекты, если таковые имеются, имеют неопределенное начальное значение ; если объект или любой из его подобъектов относятся к типу с определением const, программа сформирована неправильно.
In both cases, this statement defines b1 and copy-intializes it from a value-initialized temporary B
object.
B b1 = B();
When B
doesn't have a user-declared constructor, value-initializing causes call of B
's members to be value-initalized, and for simple types, such as int
, this means zero-initializing.
When B
does have a user-declared constructor, value-initializing tries to call the default constructor. If the members x
and y
are not listed in the constructor initializer list, then they are left uninitialized.
B b2;
In functions, local objects of POD-type without an initializer are left uninitialized. When you don't define a constructor for B
, it is a POD-class so this applies and the values of b2.x
and b2.y
have indeterminate values.
If the object is of non-POD class type, then it is default-initialized, but if this calls a constructor which leaves its members uninitialized then this makes no difference.
This is value-initialization versus no initialization. If you write
B b1 = B();
you get copy-initialization with a "value-initialized" temporary -- B(). Value-initialization of class-type objects invokes a user-defined constructor (if existant) or otherwise value-initializes the members. Value-initialization of scalar type objects is equivalent to zero-initialization. When you declare your own constructor that doesn't do anything, your scalar members are not initialized.
B b1;
is a default-initialization or no initialization at all (depending on B).
The exact initialization rules are rather complicated. See C++ standard section 8.5 "Initializers".
i tried on vc6 and Visual Studio 2005 i am getting below result in both:Could you please post disassemble code generated , Like below i have posted disassemble code for 2005
x:-858993460
y:-858993460
x:-858993460
y:-858993460
B b1 = B(); //init1
0043DEDE lea ecx,[b1]
0043DEE1 call B::B (43ADD9h)
B b2; //init2
0043DEE6 lea ecx,[b2]
0043DEE9 call B::B (43ADD9h)
print(b1);
0043DEEE lea eax,[b1]
0043DEF1 push eax
0043DEF2 call print (43A302h)
0043DEF7 add esp,4
print(b2);
0043DEFA lea eax,[b2]
0043DEFD push eax
0043DEFE call print (43A302h)
0043DF03 add esp,4
О объясняет Кирилл
Другое значение: -858993460 - 0xCCCCCCCC, это значение по умолчанию для неинициализированной стековой памяти в отладочных сборках VC.
Неинициализированная куча память по умолчанию имеет значение 0xCDCDCDCD. И, конечно же, в выпускных сборках содержимое по умолчанию является случайным.
Теперь я должен признать, что не знал, что можно вызывать c'tor напрямую, как это делается в вашем примере! И я бы поклялся, что это незаконно ...