vigra icon indicating copy to clipboard operation
vigra copied to clipboard

Windows compilation error with MSVC >= 14.28

Open k-dominik opened this issue 2 years ago • 6 comments

I've been tracking compilation issues with VS2019 compilers (I was using 14.29, but I've found that the problem was most likely introduced in MSVC 14.28.

I haven't found a solution (yet) but also don't want to forget everything the next time I get to it (or someone else looks into it).

The symptom:

following compilation error:

in the end the error occurs in MSVC STL: algorithm(6928): error C3892: '_First': you cannot assign to a variable that is const

more details here, note I shortened the paths a little for readability:

..\BuildTools\VC\Tools\MSVC\14.29.30133\include\algorithm(6928): error C3892: '_First': you cannot assign to a variable that is const
...\BuildTools\VC\Tools\MSVC\14.29.30133\include\algorithm(7050): note: see reference to function template instantiation '_BidIt std::_Insertion_sort_unchecked<_RanIt,_Pr>(const _BidIt,const _BidIt,_Pr)' being compiled
        with
        [
            _BidIt=vigra::StridedScanOrderIterator<1,vigra::UInt8,vigra::UInt8 &,vigra::UInt8 *>,
            _RanIt=vigra::StridedScanOrderIterator<1,vigra::UInt8,vigra::UInt8 &,vigra::UInt8 *>,
            _Pr=std::less<void>
        ]
...\BuildTools\VC\Tools\MSVC\14.29.30133\include\algorithm(7080): note: see reference to function template instantiation 'void std::_Sort_unchecked<_RanIt,_Fn>(_RanIt,_RanIt,__int64,_Pr)' being compiled
        with
        [
            _RanIt=vigra::StridedScanOrderIterator<1,vigra::UInt8,vigra::UInt8 &,vigra::UInt8 *>,
            _Fn=std::less<void>,
            _Pr=std::less<void>
        ]
...\BuildTools\VC\Tools\MSVC\14.29.30133\include\algorithm(7085): note: see reference to function template instantiation 'void std::sort<_RanIt,std::less<void>>(const _RanIt,const _RanIt,_Pr)' being compiled
        with
        [
            _RanIt=vigra::StridedScanOrderIterator<1,vigra::UInt8,vigra::UInt8 &,vigra::UInt8 *>,
            _Pr=std::less<void>
        ]
...\vigra\vigranumpy\src\core\segmentation.cxx(1176): note: see reference to function template instantiation 'void std::sort<vigra::StridedScanOrderIterator<1,T,T &,T *>>(const _RanIt,const _RanIt)' being compiled
        with
        [
            T=vigra::UInt8,
            _RanIt=vigra::StridedScanOrderIterator<1,vigra::UInt8,vigra::UInt8 &,vigra::UInt8 *>
        ]
...\vigra\vigranumpy\src\core\segmentation.cxx(1181): note: see reference to function template instantiation 'vigra::NumpyAnyArray vigra::pythonUnique<T,1>(vigra::NumpyArray<1,vigra::Singleband<T>,vigra::StridedArrayTag>,bool)' being compiled
        with
        [
            T=npy_uint8
        ]
...\vigra\vigranumpy\src\core\segmentation.cxx(1181): note: see reference to function template instantiation 'void vigra::pyUniqueImpl<T,1,1>::def<Args>(const char *,const Args &)' being compiled
        with
        [
            T=npy_uint8,
            Args=boost::python::detail::keywords<2>
        ]
...\vigra\vigranumpy\src\core\segmentation.cxx(1181): note: see reference to function template instantiation 'void vigra::pyUniqueImpl<T,1,1>::def<Args>(const char *,const Args &)' being compiled
        with
        [
            T=npy_uint8,
            Args=boost::python::detail::keywords<2>
        ]
...\vigra\vigranumpy\src\core\segmentation.cxx(1181): note: see reference to function template instantiation 'void vigra::pyUniqueImpl<T1,1,5>::def<Args>(const char *,const Args &,const char *)' being compiled
        with
        [
            T1=npy_uint8,
            Args=boost::python::detail::keywords<2>
        ]
...\vigra\vigranumpy\src\core\segmentation.cxx(1181): note: see reference to function template instantiation 'void vigra::pyUniqueImpl<T1,1,5>::def<Args>(const char *,const Args &,const char *)' being compiled
        with
        [
            T1=npy_uint8,
            Args=boost::python::detail::keywords<2>
        ]
...\vigra\include\vigra/numpy_array_converters.hxx(803): note: see reference to function template instantiation 'void vigra::pyUnique<1,5,npy_uint8,npy_uint32,npy_uint64,npy_int64,void,void,void,void,void,void,void,void>::def<Args>(const char *,const Args &,const char *) const' being compiled
        with
        [
            Args=boost::python::detail::keywords<2>
        ]
...\vigra\include\vigra/numpy_array_converters.hxx(803): note: see reference to function template instantiation 'void vigra::pyUnique<1,5,npy_uint8,npy_uint32,npy_uint64,npy_int64,void,void,void,void,void,void,void,void>::def<Args>(const char *,const Args &,const char *) const' being compiled
        with
        [
            Args=boost::python::detail::keywords<2>
        ]
...\vigra\vigranumpy\src\core\segmentation.cxx(1618): note: see reference to function template instantiation 'void boost::python::multidef<vigra::pyUnique<1,5,npy_uint8,npy_uint32,npy_uint64,npy_int64,void,void,void,void,void,void,void,void>,boost::python::detail::keywords<2>>(const char *,const Functor &,const Args &,const char *)' being compiled
        with
        [
            Functor=vigra::pyUnique<1,5,npy_uint8,npy_uint32,npy_uint64,npy_int64,void,void,void,void,void,void,void,void>,
            Args=boost::python::detail::keywords<2>
        ]

I found a discussion related to the above error here: https://developercommunity.visualstudio.com/t/VS2019-1684---c-const-issue:-error-C/1320890#T-N1325280

Bottom line seems to be that the vigra iterator implementation is "wrong" and de-referencing a const iterator should not return a const reference.

I followed the trail a bit to

https://github.com/ukoethe/vigra/blob/574de5743342f67408e015823d375b1c00281630/include/vigra/multi_iterator.hxx#L312-L315

and

https://github.com/ukoethe/vigra/blob/574de5743342f67408e015823d375b1c00281630/include/vigra/multi_iterator_coupled.hxx#L661-L666

, and finally to

https://github.com/ukoethe/vigra/blob/574de5743342f67408e015823d375b1c00281630/include/vigra/multi_handle.hxx#L932-L940

.

As far as I understand the problem, the solution should be removing the const from the returned reference. However, I didn't manage to do it in a way that would compile.

k-dominik avatar Nov 07 '22 15:11 k-dominik

Looks like on cf even the python 3.11 vigra package is built with MSVC 14.16. I'll propose this as a workaround.

k-dominik avatar Nov 09 '22 12:11 k-dominik

chatgpt says to look at the usage of std:sort

https://github.com/ukoethe/vigra/blob/master/vigranumpy/src/core/segmentation.cxx#L1176

It says that begin and end may be returning const iterators, which would be stopping sort from swapping values, but I can't find anything about this.

hmaarrfk avatar Oct 01 '23 02:10 hmaarrfk

i'm somewhat confused, but it feel like the iterators are defined in: https://github.com/ukoethe/vigra/blob/master/include/vigra/multi_array.hxx#L1923 https://github.com/ukoethe/vigra/blob/502d5bc7146bee0abf88f95396df22bfdda0f498/include/vigra/multi_array.hxx#L755

hmaarrfk avatar Feb 04 '24 18:02 hmaarrfk

bummer, when I saw you recompiling I had the vague memory of fixing this - but apparently I haven't :/

k-dominik avatar Feb 05 '24 11:02 k-dominik

I think we have to introduce cbegin and cend

hmaarrfk avatar Feb 05 '24 12:02 hmaarrfk

Problem remains also with VS2022, see https://github.com/conda-forge/vigra-feedstock/pull/129

h-vetinari avatar Feb 05 '24 12:02 h-vetinari

@a-detiste if you have any ideas here that would be great to see!

hmaarrfk avatar Aug 04 '24 18:08 hmaarrfk

I think i finally figured it out.

The MultiArrayView needs to implement the dereferencing pointer for the sort call in unique to work.

https://github.com/ukoethe/vigra/pull/573 passes, but breaks the call to unique

hmaarrfk avatar Aug 11 '24 13:08 hmaarrfk