Reputation: 574
Take a lot at this (working) code
class MyClass {
public:
double data[6];
double func() const {
return data[1] + 2*data[3];
}
};
double takeMyClassReference(const MyClass &obj) {
return obj.func();
}
void construct(const double y[]) {
const MyClass *obj = reinterpret_cast<const MyClass *>(y);
double val = takeMyClassReference(*obj);
// do something with val
}
this code does what I want and it is efficient, the start of construct was translated to
movsd 24(%rdi), %xmm0
addsd %xmm0, %xmm0
addsd 8(%rdi), %xmm0
which is as efficient as it gets.
Is it possible to write this in a safer way, without a reinterpret_cast, but without sacrificing speed? I cannot change the signature of construct
or takeMyClassReference
.
Upvotes: 1
Views: 276
Reputation: 574
If you're willing to move from MyClass owning the data, to MyClass not owning the data.
class MyClass {
public:
double *data;
double func() const {
return data[1] + 2*data[3];
}
};
void construct(double y[]) {
MyClass obj;
obj.data = y;
double val = takeMyClassReference(obj);
// do something with val
}
Upvotes: 1
Reputation: 39778
The only allowed way of doing this is with std::memcpy
:
void construct(const double y[]) {
MyClass x;
std::memcpy(&x,y,sizeof x);
double val = takeMyClassReference(x);
// do something with val
}
Clang already optimizes this perfectly; ICC comes close (but misses the strength reduction of using addition), while GCC generates useless stack stores (including one after the math, oddly).
Upvotes: 2