The following C++ Code and Makefile produce a compilation error incomprehensible (to me). Can somebody explain
What precisely is the problem?
What needs to be done to fix this code? Can you give an example?
I had this code compile successfully on a GCC in Cygwin, so I am not even sure which compiler I can trust. I am attaching the cpp file (test.cpp), my makefile (using clang because the GCC error message is even worse) and the actual error message on running make.
test.cpp:
#include <array>
#include <vector>
#include <map>
#include <algorithm>
class Foo
{
public:
Foo(
const std::vector<std::array<int,3>> inputdata
);
private:
std::vector< std::array<int,2> > membervariable;
};
Foo::Foo(
const std::vector<std::array<int,3>> inputdata
)
:
membervariable( 0 )
{
/* 1. create all edges, allocate memory */
membervariable.resize( inputdata.size() * 3 );
for( int t = 0; t < inputdata.size(); t++ )
for( int ei = 0; ei < 3; ei++ )
{
membervariable[ 0 * inputdata.size() + t ] = { inputdata[t][0], inputdata[t][1] };
membervariable[ 1 * inputdata.size() + t ] = { inputdata[t][0], inputdata[t][2] };
membervariable[ 2 * inputdata.size() + t ] = { inputdata[t][1], inputdata[t][2] };
}
std::sort( membervariable.begin(), membervariable.end() );
auto it = std::unique( membervariable.begin(), membervariable.end() );
membervariable.resize( it - membervariable.begin() );
}
makefile:
CC = clang++ -O0 -g -std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -pedantic -Wall -Wextra -Wno-unused-variable -Wno-sign-compare -Wno-missing-braces -Wmissing-field-initializers -Werror=implicit
# CC = g++ -O0 -g -std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -pedantic -Wall -Wextra -Wno-unused-variable -Wno-sign-compare -Wno-missing-braces -Wmissing-field-initializers -Werror=implicit
test.o: test.cpp
$(CC) test.cpp -c -o test.o
Output on envoking make and clang version:
$ make
clang++ -O0 -g -std=c++11 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -pedantic -Wall -Wextra -Wno-unused-variable -Wno-sign-compare -Wno-missing-braces -Wmissing-field-initializers -Werror=implicit test.cpp -c -o test.o
In file included from test.cpp:3:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/map:61:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_map.h:63:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/tuple:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/array:338:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/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/5.4.0/../../../../include/c++/5.4.0/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/5.4.0/../../../../include/c++/5.4.0/bits/stl_algobase.h:148:7: note: in instantiation of exception
specification for 'swap<int, 2>' requested here
swap(*__a, *__b);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:84:11: note: in instantiation of function template
specialization 'std::iter_swap<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *, std::__cxx1998::vector<std::__debug::array<int, 2>,
std::allocator<std::__debug::array<int, 2> > > >, std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int,
2> > > > >' requested here
std::iter_swap(__result, __b);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:1916:12: note: in instantiation of function template
specialization 'std::__move_median_to_first<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >, __gnu_cxx::__ops::_Iter_less_iter>'
requested here
std::__move_median_to_first(__first, __first + 1, __mid, __last - 1,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:1948:11: note: in instantiation of function template
specialization 'std::__unguarded_partition_pivot<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >, __gnu_cxx::__ops::_Iter_less_iter>'
requested here
std::__unguarded_partition_pivot(__first, __last, __comp);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:1963:9: note: in instantiation of function template
specialization 'std::__introsort_loop<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >, long,
__gnu_cxx::__ops::_Iter_less_iter>' requested here
std::__introsort_loop(__first, __last,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_algo.h:4698:12: note: in instantiation of function template
specialization 'std::__sort<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >, __gnu_cxx::__ops::_Iter_less_iter>'
requested here
std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter());
^
test.cpp:40:10: note: in instantiation of function template specialization
'std::sort<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::__debug::array<int, 2> *,
std::__cxx1998::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > >,
std::__debug::vector<std::__debug::array<int, 2>, std::allocator<std::__debug::array<int, 2> > > > >' requested here
std::sort( membervariable.begin(), membervariable.end() );
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/debug/array:84:7: note: 'swap' declared here
void
^
1 error generated.
makefile:6: recipe for target 'test.o' failed
make: *** [test.o] Error 1
$ clang++ --version
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$
The error messages shown in the question concerns a bug in the standard (LWG issue 2456) that GCC's standard library had implemented to the letter. GCC's compiler didn't diagnose the problem with the resulting code (otherwise the bug would have been discovered earlier), but the version of clang you used does. IIRC clang later added a special hack to allow this particular usage to compile, so the "fix" is to use a newer version of GCC or a newer version of Clang or both.