This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen

Bug 1776

Summary: subvector_stl_iterator::operator-> triggers 'taking address of rvalue' warning
Product: Eigen Reporter: James Beach <james>
Component: Core - generalAssignee: Nobody <eigen.nobody>
Status: RESOLVED FIXED    
Severity: Compilation Problem CC: chtz, gael.guennebaud, jacob.benoit.1
Priority: Normal Keywords: test-needed
Version: 3.4 (development)   
Hardware: All   
OS: All   
Whiteboard:
Bug Depends on:    
Bug Blocks: 814    

Description James Beach 2019-11-14 08:33:17 UTC
Given the following:

    auto x = Eigen::ArrayXXd(2, 3);
    x << 0.0, 1.0, 2.0,
         3.0, 4.0, 5.0;
    
    for (auto it = x.colwise().cbegin(); it != x.colwise().cend(); ++it)
        std::cout << "x = " << it->coeff(0) << '\n';

GCC 9.2.1 reports:

    .../src/Core/StlIterators.h:254:48: error: taking address of rvalue [-fpermissive]

No such warning is triggered if we use operator* instead:

    std::cout << "x = " << (*it).coeff(0) << '\n';

as would be done implicitly if we were to use range-based for.
Comment 1 Gael Guennebaud 2019-11-25 22:48:02 UTC
Indeed. Another failure case is:


    auto x = Eigen::ArrayXXcd(2, 3);
    auto xpr = 2*x.col(0);
    for (auto it = xpr.cbegin(); it != xpr.cend(); ++it)
        std::cout << "x = " << it->real() << '\n';


I'm not sure how to fix this issue though.
Comment 2 Gael Guennebaud 2019-11-25 23:04:57 UTC
I found a possible fix through a proxy, within the body of subvector_stl_iterator:


    typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type value_type;
    typedef value_type  reference;

    private:
    
      struct subvector_stl_iterator_ptr
      {
        subvector_stl_iterator_ptr(value_type& a) : m_subvec(a) {}
        value_type* operator->() { return &m_subvec; }
      private:
        value_type m_subvec;
      };

    public:

      typedef subvector_stl_iterator_ptr pointer;
      pointer   operator->()        const { return ((*mp_xpr).template subVector<Direction>(m_index)); }
Comment 3 Christoph Hertzberg 2019-11-26 12:32:45 UTC
I think `value_type` should actually be `SubVectorType::PlainObject`, and `reference` what currently is `value_type` (`subvector_stl_iterator_ptr` needs to contain a `reference` of course).

operator->() could just `return pointer(operator*());`
Comment 4 Gael Guennebaud 2019-11-26 21:27:51 UTC
Make sense!
Comment 5 Gael Guennebaud 2019-12-03 13:42:07 UTC
https://bitbucket.org/eigen/eigen/commits/44810c827c77/
Summary:     Bug 1776: fix vector-wise STL iterator's operator-> using a proxy as pointer type.
This changeset fixes also the value_type definition.
Comment 6 Nobody 2019-12-04 18:55:20 UTC
-- 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/1776.