хорошо, давайте просто протестируем все это. Я могу с полной оптимизацией скомпилировать более полный пример:
void use(int &);
class classWithInt
{
public:
classWithInt() : someInt(){}
int someInt;
};
class podWithInt
{
public:
int someInt;
};
int main() {
int foo;
classWithInt bar;
podWithInt baz;
use(foo);
use(bar.someInt);
use(baz.someInt);
return 5;
}
И это вывод, который я получаю из gcc-llvm
; ModuleID = '/tmp/webcompile/_21792_0.bc'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-linux-gnu"
%struct.classWithInt = type { i32 }
define i32 @main() {
entry:
%foo = alloca i32, align 4 ; <i32*> [#uses=1]
%bar = alloca %struct.classWithInt, align 8 ; <%struct.classWithInt*> [#uses=1]
%baz = alloca %struct.classWithInt, align 8 ; <%struct.classWithInt*> [#uses=1]
%0 = getelementptr inbounds %struct.classWithInt* %bar, i64 0, i32 0 ; <i32*> [#uses=2]
store i32 0, i32* %0, align 8
call void @_Z3useRi(i32* %foo)
call void @_Z3useRi(i32* %0)
%1 = getelementptr inbounds %struct.classWithInt* %baz, i64 0, i32 0 ; <i32*> [#uses=1]
call void @_Z3useRi(i32* %1)
ret i32 5
}
declare void @_Z3useRi(i32*)
В каждом случае есть некоторые различия. В простейшем случае тип POD отличается от простого int только одним способом, он требует другого выравнивания, он выровнен на 8 байтов вместо всего 4 байтов.
Другая заметная вещь заключается в том, что POD и голое int не инициализируются. Их хранилище используется прямо из пустыни стека. Тип не-pod, имеющий нетривиальный конструктор, заставляет сохранять ноль, прежде чем экземпляр можно будет использовать для чего-либо еще.