Gael Guennebaud | aba8c9e | 2015-09-02 11:23:55 +0200 | [diff] [blame] | 1 | namespace Eigen { |
| 2 | |
| 3 | /** \page TopicPitfalls Common pitfalls |
| 4 | |
Gael Guennebaud | 6af1433 | 2018-05-29 22:37:47 +0200 | [diff] [blame] | 5 | |
Gael Guennebaud | aba8c9e | 2015-09-02 11:23:55 +0200 | [diff] [blame] | 6 | \section TopicPitfalls_template_keyword Compilation error with template methods |
| 7 | |
| 8 | See this \link TopicTemplateKeyword page \endlink. |
| 9 | |
Gael Guennebaud | 6af1433 | 2018-05-29 22:37:47 +0200 | [diff] [blame] | 10 | \section TopicPitfalls_aliasing Aliasing |
| 11 | |
| 12 | Don't miss this \link TopicAliasing page \endlink on aliasing, |
| 13 | especially if you got wrong results in statements where the destination appears on the right hand side of the expression. |
| 14 | |
Gael Guennebaud | aba8c9e | 2015-09-02 11:23:55 +0200 | [diff] [blame] | 15 | \section TopicPitfalls_auto_keyword C++11 and the auto keyword |
| 16 | |
| 17 | In short: do not use the auto keywords with Eigen's expressions, unless you are 100% sure about what you are doing. In particular, do not use the auto keyword as a replacement for a Matrix<> type. Here is an example: |
| 18 | |
| 19 | \code |
| 20 | MatrixXd A, B; |
| 21 | auto C = A*B; |
| 22 | for(...) { ... w = C * v; ...} |
| 23 | \endcode |
| 24 | |
| 25 | In this example, the type of C is not a MatrixXd but an abstract expression representing a matrix product and storing references to A and B. Therefore, the product of A*B will be carried out multiple times, once per iteration of the for loop. Moreover, if the coefficients of A or B change during the iteration, then C will evaluate to different values. |
| 26 | |
Gael Guennebaud | be5e2ec | 2015-09-02 13:04:30 +0200 | [diff] [blame] | 27 | Here is another example leading to a segfault: |
| 28 | \code |
| 29 | auto C = ((A+B).eval()).transpose(); |
| 30 | // do something with C |
| 31 | \endcode |
| 32 | The problem is that eval() returns a temporary object (in this case a MatrixXd) which is then referenced by the Transpose<> expression. However, this temporary is deleted right after the first line, and there the C expression reference a dead object. The same issue might occur when sub expressions are automatically evaluated by Eigen as in the following example: |
| 33 | \code |
| 34 | VectorXd u, v; |
| 35 | auto C = u + (A*v).normalized(); |
| 36 | // do something with C |
| 37 | \endcode |
| 38 | where the normalized() method has to evaluate the expensive product A*v to avoid evaluating it twice. On the other hand, the following example is perfectly fine: |
| 39 | \code |
| 40 | auto C = (u + (A*v).normalized()).eval(); |
| 41 | \endcode |
| 42 | In this case, C will be a regular VectorXd object. |
Gael Guennebaud | aba8c9e | 2015-09-02 11:23:55 +0200 | [diff] [blame] | 43 | */ |
| 44 | } |