Compile error in debug mode
lczech opened this issue · 11 comments
Hi there,
sparsepp works perfectly fine when compiled in release mode (with an amazingly small memory footprint, thanks!), but doesn't compile with my debug setup.
The error message comes from the debug version of my STL implementation:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/debug/array:86:52:
error: too many arguments to function call, expected single argument '__other', have 2 arguments
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/debug/array:86:52: error: too many arguments to function call, expected single argument '__other', have 2 arguments
noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
~~~~ ^~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/debug/array:264:23: note: in instantiation of exception specification for 'swap' requested here
noexcept(noexcept(__one.swap(__two)))
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_pair.h:195:25: note: in instantiation of exception specification for 'swap<unsigned int, 5>' requested here
noexcept(noexcept(swap(first, __p.first))
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_pair.h:255:23: note: in instantiation of exception specification for 'swap' requested here
noexcept(noexcept(__x.swap(__y)))
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_algobase.h:148:7: note: in instantiation of exception specification for 'swap<std::__debug::array<unsigned int, 5>, unsigned long>'
requested here
swap(*__a, *__b);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_algo.h:1351:10: note: in instantiation of function template specialization 'std::iter_swap<std::pair<std::__debug::array<unsigned
int, 5>, unsigned long> *, std::pair<std::__debug::array<unsigned int, 5>, unsigned long> *>' requested here
std::iter_swap(__p, __q);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_algo.h:1419:12: note: (skipping 7 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
std::__rotate(__first, __middle, __last,
^
[...]/sparsepp/sparsepp/spp.h:2744:26: note: in instantiation of member function 'spp::sparse_hashtable<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long>,
std::__debug::array<unsigned int, 5>, spp::spp_hash<std::__debug::array<unsigned int, 5> >, spp::sparse_hash_map<std::__debug::array<unsigned int, 5>, unsigned long,
spp::spp_hash<std::__debug::array<unsigned int, 5> >, std::equal_to<std::__debug::array<unsigned int, 5> >, spp::libc_allocator<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long> >
>::SelectKey, spp::sparse_hash_map<std::__debug::array<unsigned int, 5>, unsigned long, spp::spp_hash<std::__debug::array<unsigned int, 5> >, std::equal_to<std::__debug::array<unsigned int, 5> >,
spp::libc_allocator<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long> > >::SetKey, std::equal_to<std::__debug::array<unsigned int, 5> >, spp::libc_allocator<std::pair<const
std::__debug::array<unsigned int, 5>, unsigned long> > >::sparse_hashtable' requested here
sparse_hashtable tmp(MoveDontCopy, *this, resize_to);
^
[...]/sparsepp/sparsepp/spp.h:3276:21: note: in instantiation of member function 'spp::sparse_hashtable<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long>,
std::__debug::array<unsigned int, 5>, spp::spp_hash<std::__debug::array<unsigned int, 5> >, spp::sparse_hash_map<std::__debug::array<unsigned int, 5>, unsigned long,
spp::spp_hash<std::__debug::array<unsigned int, 5> >, std::equal_to<std::__debug::array<unsigned int, 5> >, spp::libc_allocator<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long> >
>::SelectKey, spp::sparse_hash_map<std::__debug::array<unsigned int, 5>, unsigned long, spp::spp_hash<std::__debug::array<unsigned int, 5> >, std::equal_to<std::__debug::array<unsigned int, 5> >,
spp::libc_allocator<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long> > >::SetKey, std::equal_to<std::__debug::array<unsigned int, 5> >, spp::libc_allocator<std::pair<const
std::__debug::array<unsigned int, 5>, unsigned long> > >::_resize_delta' requested here
if (_resize_delta(1))
^
[...]/sparsepp/sparsepp/spp.h:3797:29: note: in instantiation of function template specialization 'spp::sparse_hashtable<std::pair<const std::__debug::array<unsigned int, 5>, unsigned
long>, std::__debug::array<unsigned int, 5>, spp::spp_hash<std::__debug::array<unsigned int, 5> >, spp::sparse_hash_map<std::__debug::array<unsigned int, 5>, unsigned long,
spp::spp_hash<std::__debug::array<unsigned int, 5> >, std::equal_to<std::__debug::array<unsigned int, 5> >, spp::libc_allocator<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long> >
>::SelectKey, spp::sparse_hash_map<std::__debug::array<unsigned int, 5>, unsigned long, spp::spp_hash<std::__debug::array<unsigned int, 5> >, std::equal_to<std::__debug::array<unsigned int, 5> >,
spp::libc_allocator<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long> > >::SetKey, std::equal_to<std::__debug::array<unsigned int, 5> >, spp::libc_allocator<std::pair<const
std::__debug::array<unsigned int, 5>, unsigned long> > >::find_or_insert<spp::sparse_hash_map<std::__debug::array<unsigned int, 5>, unsigned long, spp::spp_hash<std::__debug::array<unsigned int, 5> >,
std::equal_to<std::__debug::array<unsigned int, 5> >, spp::libc_allocator<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long> > >::DefaultValue>' requested here
return rep.template find_or_insert<DefaultValue>(key).second;
^
[...]/foo.cpp:326:21: note: in instantiation of member function 'spp::sparse_hash_map<std::__debug::array<unsigned int, 5>, unsigned long,
spp::spp_hash<std::__debug::array<unsigned int, 5> >, std::equal_to<std::__debug::array<unsigned int, 5> >, spp::libc_allocator<std::pair<const std::__debug::array<unsigned int, 5>, unsigned long> >
>::operator[]' requested here
hashmap[ key ] = value;
My setup: Clang 3.9.1
Debug flags:
-O2 -DDEBUG -g -ggdb3 -D_GLIBCXX_DEBUG
that is, with the checked STL implementation.
Any idea what is going on here?
Thanks a lot!
Lucas
I did some more digging. The problem is the -D_GLIBCXX_DEBUG
flag, that is, the checked STL version. When removing this, compilation works. But I'd prefer to keep it.
It would be useful to know what's on line 86 of /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/debug/array
.
Even more useful would be the output of the preprocessor (add -save-temps
to your flags and look for a .ii file).
Line 86 is already printed in the detail listing of my post ;-)
Here is a bit more context. The problematic line is in the swap
function of std::array
. It seems to be the noexcept
specification that is causing trouble:
void
swap(array& __other)
noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
{ std::swap_ranges(begin(), end(), __other.begin()); }
I also got the preprocessor .ii
file: chunkify.ii.zip. Unpacked, it is 4MB, because of all the headers. Let me know if you want me to prepare something more light-weight instead.
What is the definition of your sparsepp map or set?
I'm using
spp::sparse_hash_map< typename HashFunction::DigestType, size_t >
where HashFunction::DigestType
is
using DigestType = std::array< uint32_t, 5 >;
Interesting! Because of the abstraction of DigestType
, I didn't see the connection between my hash key type and the array
that is causing the compile error. Is this an issue with the STL implementation, after all? Or am I using sparsepp wrongly?
I don't think the issue is in your code. I think it may be an issue with the checked STL, but not 100% sure. Does the issue occur if you use std::unordered_map instead of spp::sparse_hash_map?
No, using a std::unordered_map
compiles fine with the same debug settings.
By the way, if it helps, the only operations that I am doing with the map are:
// Init a map from hashes to chunk IDs.
using ChunkHashMap = spp::sparse_hash_map< typename HashFunction::DigestType, size_t >;
ChunkHashMap hash_to_chunk;
// Check if a hash is in there. If so, use the chunk ID. If not, add it.
auto const hash_it = hash_to_chunk.find( hash_digest );
if( hash_it != hash_to_chunk.end() ) {
auto const chunk_id = hash_it->second;
// ...
} else {
// ...
hash_to_chunk[ hash_digest ] = chunk_count;
}
(some variable declarations left out for simplicity)
The line that is causing the compile error is the last one, where a new element is added.
I think that the checked STL the code you quoted should have a std::
before the swap() call in the noexcept clause, otherwise it tries to call itsef swap(array& __other)
which takes a single __other argument
void
swap(array& __other)
noexcept(noexcept(std::swap(std::declval<_Tp&>(), std::declval<_Tp&>())))
{ std::swap_ranges(begin(), end(), __other.begin()); }```
Yep, that works. With the added std::
, my code compiles. I just sent a bug report to the libc++ mailing list, let's see what they say about this.
Thanks! I guess, we can close this issue then.
Short update:
It seems there were two problems involved. One with Clang (http://lists.llvm.org/pipermail/cfe-dev/2018-May/058005.html), and one with the libstdc++ (GCC) STL implementation (http://lists.llvm.org/pipermail/cfe-dev/2018-May/058017.html) - the added std
however seems not to be the correct solution. The problem was however solved in libstdc++ a while ago, so I probably just need to update, and find out why Clang uses the GCC STL implementation in my setup...
Anyway, the problem is not due to sparsepp, so all good here ;-)