Ref does not preserve zero stride

Summary

A Ref<> created from a slice expression with stride 0 has a non-zero stride between columns.

Environment

  • Operating System : Linux
  • Architecture : x64
  • Eigen Version : 7fa069ef9 (tip of tree at time of this report)
  • Compiler Version : gcc (GCC) 15.1.1 20250425
  • Compile Flags : -g
  • Vector Extension : SSE/AVX/NEON ...

Minimal Example

TEST(EigenRefs, RefWithStrideZero) {
    Eigen::ArrayXXf foo;
    foo.resize(1024, 7);

    auto check_ref_behavior = [&foo](size_t stride) {
        std::cout << "Checking stride " << stride << std::endl;
        auto slice = Eigen::seqN(2, 2, stride);

        void *col0 = foo(Eigen::seqN(0, 1024), slice).col(0).data();
        void *col1 = foo(Eigen::seqN(0, 1024), slice).col(1).data();

        Eigen::Ref<Eigen::ArrayX2f> ref = foo(Eigen::seqN(0, 1024), slice);
        void *ref_col0 = ref.col(0).data();
        void *ref_col1 = ref.col(1).data();

        if(stride == 0) {
            EXPECT_EQ(col0, col1);
        }
        EXPECT_EQ(col0, ref_col0);
        EXPECT_EQ(col1, ref_col1);
    };

    check_ref_behavior(3); // passes
    check_ref_behavior(0); // fails col1 == ref_col1 check
}

Steps to reproduce

  1. Create a 2D array.
  2. Index the array with a seqN with a zero stride, e.g. Eigen::seqN(2, 2, 0).
  3. Create a ref from this expression.
  4. The ref has a nonzero stride.

What is the current bug behavior?

In the MVCE provided, ref has an 0x1000 stride between the address of .col(0) and .col(1).

What is the expected correct behavior?

The ref should have the same address for all its columns.

Relevant logs

The MVCE prints:

Checking stride 3
Checking stride 0
test.cpp:110: Failure
Expected equality of these values:
  col1
    Which is: 0x559215693b60
  ref_col1
    Which is: 0x559215694b60

Anything else that might help

  • Have a plan to fix this issue.
Edited by George Hilliard