Suppose I have a function with Eigen types as inputs and outputs:
void aliasing_function(
const Eigen::MatrixXd & A,
Eigen::MatrixXd & B)
{
for(int i = 0;i<B.rows();i++)
{
B.row(i) = A.row(A.rows()-i-1);
}
}
This function is dangerous despite the const
on the input parameter A
because if A
and B
reference the same place in memory, writing to B
will also write onto what this function thinks is A
. Usually this is undesirable and it's called aliasing. For example consider calling with the same input as output:
aliasing_function(C,C);
Supposing that I can't/won't/refuse to change the implementation of aliasing_function
, here's proof that you can avoid aliasing problems by using the copy constructor of the Eigen type directly in the parameter (avoiding the explicitly named temporary variable, but still costing a copy probably). The call above is replaced with:
aliasing_function(Eigen::MatrixXd(C),C);
To have a tangible example:
int main()
{
using namespace std;
Eigen::MatrixXd C = (Eigen::MatrixXd(3,3)<<1,2,3,4,5,6,7,8,9).finished();
cout<<"C: "<<endl<<C<<endl;
aliasing_function(Eigen::MatrixXd(C),C);
cout<<"C: "<<endl<<C<<endl;
aliasing_function(C,C);
cout<<"C: "<<endl<<C<<endl;
}
This outputs:
C:
1 2 3
4 5 6
7 8 9
C:
7 8 9
4 5 6
1 2 3
C:
1 2 3
4 5 6
1 2 3
The last print out shows the effect of aliasing.