New user self-registration is disabled due to spam. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Bug 1213 - GCC undefined reference link error caused by anonymous enum values in default Matrix template options argument
GCC undefined reference link error caused by anonymous enum values in default...
 Status: RESOLVED FIXED None Eigen Unclassified Core - general (show other bugs) 3.2 All All High Unit Test Required Nobody 3.3 Show dependency tree / graph

 Reported: 2016-04-27 14:38 UTC by D Kessler 2016-05-18 12:04 UTC (History) 3 users (show) chtz gael.guennebaud jacob.benoit.1

Attachments
Source and Makefile demonstrating linker error using GCC 4.8.2 (1.31 KB, application/x-gzip)
2016-04-27 14:38 UTC, D Kessler
no flags Details
Give enums a name (3.76 KB, patch)
2016-05-06 09:37 UTC, Christoph Hertzberg
no flags Details | Diff

 D Kessler 2016-04-27 14:38:31 UTC 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, std::allocator > > const&)': testilib.cpp:(.text+0x14): undefined reference to bool TriangulatePolygon(std::vector, std::allocator > > 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 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. Christoph Hertzberg 2016-04-28 09:58:35 UTC 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 Christoph Hertzberg 2016-04-28 10:08:58 UTC 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. D Kessler 2016-04-28 13:34:44 UTC 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? Gael Guennebaud 2016-05-04 11:14:38 UTC I would also go for naming the enum. Christoph Hertzberg 2016-05-06 09:37:58 UTC 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. Christoph Hertzberg 2016-05-11 17:30:27 UTC 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 Gael Guennebaud 2016-05-18 11:42:12 UTC renaming pass: https://bitbucket.org/eigen/eigen/commits/2bbccd1a8317 and backport: https://bitbucket.org/eigen/eigen/commits/408aa1462583 Gael Guennebaud 2016-05-18 12:04:14 UTC Add regression unit test: https://bitbucket.org/eigen/eigen/commits/c432bf8301a3

 Note You need to log in before you can comment on or make changes to this bug.