Warning in first_aligned with custom operator
Submitted by nafur
Assigned to Nobody
Link to original bugzilla bug (#921)
Version: 3.2
Operating system: Linux
Description
Created attachment 510
First test case.
eigen3/Eigen/src/Core/util/Memory.h:485 reads:
return std::min<Index>( (PacketSize - (Index((size_t(array)/sizeof(Scalar))) & PacketAlignedMask)) & PacketAlignedMask, size);
We define the following operator
template<typename C>
inline C operator-(const C& lhs, const std::shared_ptr<const A>& rhs);
that may end up in the global namespace (when a user uses "using namespace")
When compiling with gcc (4.9.2), this results in a warning as the compiler is not sure about which operator to choose.
The minimal example attached to this ticket results in the following warning:
In file included from /usr/include/eigen3/Eigen/Core:256:0,
from /usr/include/eigen3/Eigen/Dense:1,
from ~/src/tests/debug/Test_EigenWarning.cpp:5:
/usr/include/eigen3/Eigen/src/Core/util/Memory.h: In instantiation of ‘Index Eigen::internal::first_aligned(const Scalar*, Index) [with Scalar = std::complex<double>; Index = long int]’:
/usr/include/eigen3/Eigen/src/Core/Assign.h:403:78: required from ‘static void Eigen::internal::assign_impl<Derived1, Derived2, 3, 0, Version>::run(Derived1&, const Derived2&) [with Derived1 = Eigen::Matrix<std::complex<double>, -1, 1>; Derived2 = Eigen::Matrix<std::complex<double>, -1, 1>; int Version = 0]’
/usr/include/eigen3/Eigen/src/Core/Assign.h:500:111: required from ‘Derived& Eigen::DenseBase<Derived>::lazyAssign(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<std::complex<double>, -1, 1>; Derived = Eigen::Matrix<std::complex<double>, -1, 1>]’
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:414:46: required from ‘Derived& Eigen::PlainObjectBase<Derived>::lazyAssign(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<std::complex<double>, -1, 1>; Derived = Eigen::Matrix<std::complex<double>, -1, 1>]’
/usr/include/eigen3/Eigen/src/Core/Assign.h:520:123: required from ‘static Derived& Eigen::internal::assign_selector<Derived, OtherDerived, false, false>::run(Derived&, const OtherDerived&) [with Derived = Eigen::Matrix<std::complex<double>, -1, 1>; OtherDerived = Eigen::Matrix<std::complex<double>, -1, 1>]’
/usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:621:105: required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<std::complex<double>, -1, 1>; Derived = Eigen::Matrix<std::complex<double>, -1, 1>]’
/usr/include/eigen3/Eigen/src/Core/Matrix.h:288:31: required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>&) [with _Scalar = std::complex<double>; int _Rows = -1; int _Cols = 1; int _Options = 0; int _MaxRows = -1; int _MaxCols = 1]’
~/src/tests/debug/Test_EigenWarning.cpp:17:47: required from here
/usr/include/eigen3/Eigen/src/Core/util/Memory.h:485:41: note: candidate 1: operator-(int, long int) <built-in>
return std::min<Index>( (PacketSize - (Index((size_t(array)/sizeof(Scalar))) & PacketAlignedMask))
^
~/src/tests/debug/Test_EigenWarning.cpp:10:3: note: candidate 2: C operator-(const C&, const std::shared_ptr<const A>&) [with C = Eigen::internal::first_aligned(const Scalar*, Index) [with Scalar = std::complex<double>; Index = long int]::<anonymous enum>]
C operator-(const C& c, const std::shared_ptr<const A>& m) {
In the second attachment, I copied the essential code from Memory.h to trigger a smaller warning:
~/src/tests/debug/Test_EigenWarning2.cpp: In function ‘int main()’:
~/src/tests/debug/Test_EigenWarning2.cpp:17:53: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
std::cout << (PacketSize - (tmp & PacketAlignedMask)) << std::endl;
^
~/src/tests/debug/Test_EigenWarning2.cpp:17:53: note: candidate 1: operator-(int, long int) <built-in>
~/src/tests/debug/Test_EigenWarning2.cpp:10:3: note: candidate 2: C operator-(const C&, const std::shared_ptr<const A>&) [with C = main()::<anonymous enum>]
C operator-(const C& c, const std::shared_ptr<const A>& m) {
While I have no idea why gcc even thinks about converting the integer type to a std::shared_ptr, casting the first argument to an int resolves this problem for me.
Attachment 510, "First test case.":
Test_EigenWarning.cpp