Reputation: 210
I'm struggling to understand why my compilers (g++ 8.1.0 and clang++ 6.0.0) treat POD (plain-old-data) and non-POD code differently.
Test code:
#include <iostream>
struct slong {
int i;
~slong() { i = 0; }
};
int get1(slong x) { return 1+x.i; }
int main() {
std::cerr << "is_pod(slong) = " << std::is_pod<slong>::value << std::endl;
}
defines a class slong
with a destructor (hence not POD) and the compiler, with -Ofast, will produce for get1
movl (%rdi), %eax
incl %eax
but when I comment out the destructor (so slong
becomes POD) I get
leal 1(%rdi), %eax
Of course the performance issue is minor; still I'd like to understand. In other (more complicated) cases I also noticed more significant code differences.
Upvotes: 3
Views: 534
Reputation: 28278
Note that movl
accesses memory, while leal
doesn't.
When passing a struct
to a function by value, ABI can stuff it into a register (rdi
) if it's POD.
If the struct
is not POD, ABI must pass it on stack (presumably because the code may need its address to call the destructor, access the vtable and do other complicated stuff). So accessing its member requires indirection.
Upvotes: 4