vigra
vigra copied to clipboard
Windows compilation error with MSVC >= 14.28
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.
Looks like on cf even the python 3.11 vigra package is built with MSVC 14.16. I'll propose this as a workaround.
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.
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
bummer, when I saw you recompiling I had the vague memory of fixing this - but apparently I haven't :/
I think we have to introduce cbegin and cend
Problem remains also with VS2022, see https://github.com/conda-forge/vigra-feedstock/pull/129
@a-detiste if you have any ideas here that would be great to see!
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