Created attachment 701 [details] Source and Makefile demonstrating linker error using GCC 4.8.2 Not sure if this is a bug in GCC or a difference in interpretation of the C++ standard, but we've run into a tricky link error when using the Eigen Matrix class in a templated function defined in a library that is used by another library. The attached code demonstrates the problem, which occurs with GCC 4.2.8 on an Ubuntu Linux system, although it appears to be the same problem as discussed on http://stackoverflow.com/questions/24730981/undefined-reference-error-from-gcc-using-a-template-with-a-stdvector-and-an-ei The specific error, for the attached example, is: ./libitest.a(testilib.o): In function `TriangulateIt(std::vector<Eigen::Matrix<float, 3, 1, 0, 3, 1>, std::allocator<Eigen::Matrix<float, 3, 1, 0, 3, 1> > > const&)': testilib.cpp:(.text+0x14): undefined reference to `bool TriangulatePolygon<float, 3>(std::vector<Eigen::Matrix<float, 3, 1, ((Eigen::._86)0)|((((3)==(1))&&((1)!=(1)))?((Eigen::._86)1) : ((((1)==(1))&&((3)!=(1)))?((Eigen::._86)0) : ((Eigen::._86)0))), 3, 1>, std::allocator<Eigen::Matrix<float, 3, 1, ((Eigen::._86)0)|((((3)==(1))&&((1)!=(1)))?((Eigen::._86)1) : ((((1)==(1))&&((3)!=(1)))?((Eigen::._86)0) : ((Eigen::._86)0))), 3, 1> > > const&)' The issue seems to be the use of anonymous enum values in the expression defining the default value for the options parameter of the Matrix template, and that GCC is not fully evaluating the expression before storing the template function signature in a library. Further, the type name generated for anonymous enums ("Eigen::._86" in the error above) appears to use a counter, which can be different for different compilation units (in the example provided, the type name is different for the testlib and testilib libraries, where the function definition is in the testlib library and is being referenced by the testilib library). One solution is to explicitly provide a value for the fourth, "options" template argument of the Matrix class, as in this example from the attached files: #define VecDT_ Eigen::Matrix<T,dim,1,0> Another solution that appears to work is to provide a name for the anonymous enum involved, defined in Constants.h. For example (adding "MatrixOptionsType"): /** \ingroup enums * Enum containing possible values for the \p _Options template parameter of * Matrix, Array and BandMatrix. */ enum MatrixOptionsType { /** Storage order is column major (see \ref TopicStorageOrders). */ ColMajor = 0, /** Storage order is row major (see \ref TopicStorageOrders). */ RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that /** Align the matrix itself if it is vectorizable fixed-size */ AutoAlign = 0, /** Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation DontAlign = 0x2 }; I haven't worked with the interior of the Eigen code to know if this is a reasonable solution, or if the burden should be on the user of the Eigen library to avoid the GCC issue by explicitly giving a value for the Matrix options template parameter. Note that a colleague has reported to me that the problem still occurs in Eigen 3.3beta1, but that it doesn't occur unless the code is compiled with the -march=native.
I can confirm this. We could solve this issue by declaring ColMajor, RowMajor, AutoAlign, DontAlign as static const int, instead of as enum. (We'll probably need to do the same for other constants) I'm not sure if this breaks anything. Somewhat related (but not quite the same) are Bug 1207 and this discussion: http://thread.gmane.org/gmane.comp.lib.eigen/4960
For the record: I tested with g++-4.8.4 (which has the issue) and with clang++-3.6 (which apparently does not have it). And as you stated, giving the enum a name also solves the issue.
Thanks. From an outsider's perspective, it seems that giving the enum a name is the least disruptive solution noted so far, but I'm sure I'm not aware of all of the internal issues involved. In your opinion, is this actually a bug in GCC? Should I be submitting a bug report with that group?
I would also go for naming the enum.
Created attachment 703 [details] Give enums a name Attached is a suggestion for naming the currently unnamed enums. Any objections or other/better suggestions? Once we name them, the names will likely stay for a while.
I pushed it here: https://bitbucket.org/eigen/eigen/commits/3a39911ae75 As long as 3.3 is not released feel free to change the naming. We should still write a unit test and consider backporting to 3.2
renaming pass: https://bitbucket.org/eigen/eigen/commits/2bbccd1a8317 and backport: https://bitbucket.org/eigen/eigen/commits/408aa1462583
Add regression unit test: https://bitbucket.org/eigen/eigen/commits/c432bf8301a3
-- GitLab Migration Automatic Message -- This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/1213.