Thanks to visit codestin.com
Credit goes to github.com

Skip to content

<ranges>: repeat_view<T, unsigned int> emits truncation warnings #4251

@StephanTLavavej

Description

@StephanTLavavej

Found by std/ranges/range.factories/range.repeat.view/iterator/minus.pass.cpp in the upcoming libcxx update.

D:\GitHub\STL\out\x64>type meow.cpp
#include <cassert>
#include <iostream>
#include <ranges>
using namespace std;

int main() {
    auto rv    = views::repeat(1729, 20u);
    auto first = rv.begin();
    auto last  = rv.end();
    assert(last - first == 20);
    first += 2;
    last -= 3;
    assert(last - first == 15);
}
D:\GitHub\STL\out\x64>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od meow.cpp && meow
meow.cpp
D:\GitHub\STL\out\x64\out\inc\ranges(1574): warning C4244: '-=': conversion from '__int64' to 'unsigned int', possible loss of data
D:\GitHub\STL\out\x64\out\inc\ranges(1574): note: the template instantiation context (the oldest one first) is
D:\GitHub\STL\out\x64\out\inc\ranges(1484): note: while compiling class 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator'
        with
        [
            _Ty=int
        ]
D:\GitHub\STL\out\x64\out\inc\ranges(1560): note: while compiling class template member function 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator &std::ranges::repeat_view<_Ty,unsigned int>::_Iterator::operator -=(__int64) noexcept'
        with
        [
            _Ty=int
        ]
meow.cpp(12): note: see the first reference to 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator::operator -=' in 'main'
        with
        [
            _Ty=int
        ]
D:\GitHub\STL\out\x64\out\inc\ranges(1557): warning C4244: '+=': conversion from '__int64' to 'unsigned int', possible loss of data
D:\GitHub\STL\out\x64\out\inc\ranges(1557): note: the template instantiation context (the oldest one first) is
D:\GitHub\STL\out\x64\out\inc\ranges(1543): note: while compiling class template member function 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator &std::ranges::repeat_view<_Ty,unsigned int>::_Iterator::operator +=(__int64) noexcept'
        with
        [
            _Ty=int
        ]
meow.cpp(11): note: see the first reference to 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator::operator +=' in 'main'
        with
        [
            _Ty=int
        ]

At first glance, it doesn't seem that the user code is provoking these warnings, instead it's how the STL widens and narrows types.

In our implementation, I see that we have:

/* [[no_unique_address]] */ _Index_type _Current{};

and then we're performing debug checks with static_cast<_Index_type>(_Off) and finally saying _Current += _Off;:

STL/stl/inc/ranges

Lines 1543 to 1559 in cf1313c

constexpr _Iterator& operator+=(difference_type _Off) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
if (_Off > 0) {
_STL_VERIFY(_Current <= (numeric_limits<_Index_type>::max)() - static_cast<_Index_type>(_Off),
"cannot advance repeat_view iterator past end (integer overflow)");
} else {
_STL_VERIFY(_Current >= (numeric_limits<_Index_type>::min)() - static_cast<_Index_type>(_Off),
"cannot advance repeat_view iterator before begin (integer overflow)");
}
if constexpr (!is_same_v<_Bo, unreachable_sentinel_t>) {
_STL_VERIFY(_Current + _Off >= 0, "cannot subtract below 0");
}
#endif // _CONTAINER_DEBUG_LEVEL > 0
_Current += _Off;
return *this;
}

My vague guess is that after the debug checks, we should be able to use static_cast<_Index_type>(_Off) to avoid the warning. However, I'm not sure if we should be checking that difference_type _Off can be losslessly static_cast<_Index_type>(_Off) in the first place, which is why I'm filing this issue instead of just changing the implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!rangesC++20/23 ranges

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions