I plugged this into Godbolt and was pleasantly surprised that these two function calls a()
and b()
are equivalent under anything other than -O0
(using most major compilers):
#include <cmath>
struct A {
int a,b,c;
float bar() {
return sqrt(a + b + c);
}
};
struct B {
int a[3];
float bar() {
int ret{0};
for (int i = 0; i<3; ++i) {
ret += a[i];
}
return sqrt(ret);
}
};
float a() {
A a{55,67,12};
return a.bar();
}
float b() {
B b{55,67,12};
return b.bar();
}
The Godbolt output is:
a():
movss xmm0, DWORD PTR .LC0[rip]
ret
b():
movss xmm0, DWORD PTR .LC0[rip]
ret
.LC0:
.long 1094268577
I am no assembly expert, but I'm wondering if this could actually be true, that they are doing identical work. I can't even see where in this assembly there is a call to a sqrt
, or what that long
"constant" (?) is doing in there.