Bugzilla – Bug 1328
3.3-rc1 doesn't compile on gcc 4.2.1 (apple)
Last modified: 2016-11-03 08:07:48 UTC
my program that used Eigen 3.2.x happily with gcc 4.2.1 doesn't compile with the newer version; here are the error messages that I get (also appear when building unit tests):
Eigen/src/Core/util/XprHelper.h:194: error: expected primary-expression before ‘bool’
Eigen/src/Core/util/XprHelper.h:194: error: expected ‘>’ before ‘bool’
Eigen/src/Core/util/XprHelper.h:210: error: template argument 4 is invalid
Eigen/src/Core/util/XprHelper.h:223: error: template argument 4 is invalid
Eigen/src/Core/util/Meta.h:392: error: no matching function for call to ‘Eigen::internal::scalar_identity_op<double>::operator()() const’
Eigen/src/Core/util/Meta.h: In instantiation of ‘Eigen::internal::has_unary_operator<Eigen::internal::scalar_identity_op<double>, long int>’
If C++11 is a requirement now, this needs to be stated explicitly in the docs?
We still support C++98/C++03, but older compilers usually have some deficits in supporting the standard.
We only claim to support gcc 4.4 and newer now:
Note that gcc 4.2.1 was released more than 9 years ago and the 4.2 series is not maintained since 2008:
ok, sorry, I must have overlooked this.
yeah, it's old but is the default compiler for my macos, c'est la vie!
For the record, the offending code is:
template<int ArrayBytes, int AlignmentBytes,
bool Match = bool((ArrayBytes%AlignmentBytes)==0),
bool TryHalf = bool(AlignmentBytes>EIGEN_MIN_ALIGN_BYTES) >
It seems that the comparison operator is miss-interpreted as the termination of the template declaration. If changing it to:
is all you need to make 4.2 happy, then let's do it!
thanks, that helped to get rid of that problem, but there is another one remaining.
in Eigen/src/Core/util/Meta.h, lines 392, 401 and 410, a handful of errors like this:
error: no matching function for call to 'Eigen::internal::linspaced_op<int, long long int __vector__, false>::operator()() const'
Eigen/src/Core/util/Meta.h: In instantiation of 'Eigen::internal::has_binary_operator<Eigen::internal::scalar_constant_op<int>, long int>':Eigen/src/Core/functors/NullaryFunctors.h:163: instantiated from 'Eigen::internal::functor_has_linear_access<Eigen::internal::scalar_constant_op<int> >'
Eigen/src/Core/CoreEvaluators.h:461: instantiated from ...
I don't see what exactly it complains about, but if it is similarly easy to fix, that would be great.
ah, here we go. I expected such trouble some issues. All old compilers complain about this part, including MSVC 2010 and ICC 11. Making this piece of code compatible with all version of MSVC >= 2012, gcc >= 4.4 and clang has been extremely tedious. Making those old compilers truly happy might just be impossible. Since this is affecting several old compilers, a workaround, would be to specialize those structures for our internal nullary functors (there are only 3). Of course, users of such compilers would not be able to benefits from the automatic detection of operator() (), (i), and (i,j) for custom nullary functors, but that's acceptable I guess.
I've pushed a workaround for old compilers: https://bitbucket.org/eigen/eigen/commits/153266fe2b36
Let us known if that works for you as well.
Wow, now it does take **ages** to compile! (10 minutes for a single source file on my machine!)
The compilation itself proceeds without errors, but then the linker complains:
ld: duplicate symbol double __vector Eigen::internal::pinsertlast<double __vector>(double __vector const&, Eigen::internal::unpacket_traits<double __vector>::type)in obj/math_linalg.o and obj/math_fit.o
and this is fairly strange because this is a template function for which the instantiations in different object files are supposed to be coalesced together by the linker...
I fixed the missing inline keywords.
Regarding the 10mn of compilation, I guess you are running out of memory and that your system is swapping.
That almost worked; I had to make similar changes in Core/arch/SSE/PacketMath.h and then all went fine. Thanks! You're right, 2Gb of memory is clearly not enough for the compiler to chew these intricate constructs...
On a different machine icc 13.0 wasn't complaining about duplicate symbols, although it ranted about "warning #2536: type qualifiers are meaningless here" in src/Core/ProductEvaluators.h lines 570,571,1305. And also the BDCSVD suffers from a larger floating-point errors (~1e-10 for a 500x500 matrix) when compiled with intel; I think we already discussed its too aggressive optimization strategy a few month ago (it wasn't even finishing the computation at all back then!)
What's missing in Core/arch/SSE/PacketMath.h? All pinsertlast functions are now declared inline.
Regarding the warnings, I fixed the first two, but there is no line 1305 in ProductEvaluators.h.
For ICC and lack of accuracy, yes, you need to disable some unsafe math optimizations. Perhaps it could be possible to temporarily disable them in Eigen using pragamas??? If you manage to do so, then please send us a patch!
At least, this needs to be documented.
I see you are using BDCSVD! That piece of code is indeed highly demanding on the compiler as it instantiates a very large part of Eigen.
> What's missing in Core/arch/SSE/PacketMath.h? All pinsertlast functions are now declared inline.
ah! sorry, it was already there in the patch, I just did not scroll down the entire screen!:)
line 1305 was in src/Core/CoreEvaluators.h, sorry for confusion.
Yes, compiling with -fp-model precise restores the accuracy, but may negatively impact the performance elsewhere.
I tried to add #pragma float_control(precise,on) before the BDCSVD class is instantiated, or at the beginning of BDCSVD::compute, but that had no effect.
I've also played with #pragma float_control but it has to be put in your .cpp file. So there is no solution on Eigen's side.