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.
Note that
movlaccesses memory, whilelealdoesn't.When passing a
structto a function by value, ABI can stuff it into a register (rdi) if it's POD.If the
structis 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.