There is this code:
#include <iostream>
class KlasaNiePOD{
public:
int a;
~KlasaNiePOD(){}
};
int main() {
KlasaNiePOD obiekt1; // first case
std::cout << obiekt1.a << std::endl; // -1075234152
KlasaNiePOD obiekt2 = KlasaNiePOD(); // second case
std::cout << obiekt2.a << std::endl; // 0
return 0;
}
Why in the first case ‘a’ is not initialized, but in second case it is? Shouldn’t be called constructor always in non-POD classes?
Edit:
Fragment from assembly:
.globl main
.type main, @function
main:
.LFB960:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
.cfi_lsda 0x0,.LLSDA960
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
andl $-16, %esp
pushl %esi
pushl %ebx
subl $40, %esp
movl 28(%esp), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp) # std::cout << obiekt1.a << std::endl;
.LEHB0:
.cfi_escape 0x10,0x3,0x7,0x55,0x9,0xf0,0x1a,0x9,0xf8,0x22
.cfi_escape 0x10,0x6,0x7,0x55,0x9,0xf0,0x1a,0x9,0xfc,0x22
call _ZNSolsEi
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
.LEHE0:
movl $0, 24(%esp) # Here obiekt2.a = 0
movl 24(%esp), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp) # std::cout << obiekt2.a << std::endl;
.LEHB1:
call _ZNSolsEi
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
.LEHE1:
movl $0, %ebx
leal 24(%esp), %eax
movl %eax, (%esp)
call _ZN11KlasaNiePODD1Ev
leal 28(%esp), %eax
movl %eax, (%esp)
call _ZN11KlasaNiePODD1Ev
movl %ebx, %eax
addl $40, %esp
popl %ebx
popl %esi
movl %ebp, %esp
popl %ebp
ret
This is default-initialised; since it doesn’t have a default constructor, members with a fundamental type (which includes numeric types) are left uninitialised.
The temporary
KlasaNiePOD()is value-initialised; since it doesn’t have a default constructor, members with a numeric type are initialised to zero.