[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#777791: ball: ftbfs with GCC-5

Hello Andreas, hello list(s),

I tried to reproduce this build failure on a current sid and investigate
a bit.  On my machine it outputs the same basic error messages (although
the line numbers in the basic_string template file are a bit different).

I try to quote the error message partially so it becomes a bit clearer
what is really going on:

On 01/07/2016 01:12 PM, Andreas Tille wrote:
> /build/ball-1.4.3~beta1/include/BALL/DATATYPE/string.iC: In member function 'BALL::String& BALL::String::insert(BALL::String::const_iterator, std::initializer_list<char>)':
> /build/ball-1.4.3~beta1/include/BALL/DATATYPE/string.iC:1379:19: error: no matching function for call to 'std::__cxx11::basic_string<char>::insert(BALL::String::const_iterator&, std::initializer_list<char>&)'
>   str_.insert(p, li);
>                    ^


BALL::String::const_iterator is a typedef for std::string::const_iterator

> /usr/include/c++/5/bits/basic_string.h:1308:7: note: candidate: void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::insert(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::iterator, std::               initializer_list<_Tp>) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*,    std::__cxx11::basic_string<char> >; typename __gnu_cxx::__alloc_traits<typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_CharT>::other>::pointer = char*]
>        insert(iterator __p, initializer_list<_CharT> __l)
>        ^
> /usr/include/c++/5/bits/basic_string.h:1308:7: note:   no known conversion for argument 1 from 'BALL::String::const_iterator {aka __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >}' to 'std::__cxx11::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >}'

In essence this says:

(1) No matching function for
string::insert(string::const_iterator, initializer_list<char>),

because (when trying the correct overload),
(2) Cannot convert from string::const_iterator to string::iterator

Which raises the question: Why does the compiler try to convert to a
non-const-iterator in the first place?

According to both cplusplus.com[1] and cppreference.com[2] the insert
function with an initializer_list as second parameter should take a
*const_*iterator directly.

I have condensed this into a simple test case (see attached string.cc)
and for me, this testcase fails in the same way as ball when called with

Try it like this:

g++ -std=c++11 string.cc -o string && ./string
(long error message)

Now, with clang++ this fails too:

clang++ -std=c++11 string.cc -o string && ./string
(a bit shorter error message, but essentially the same)

However, if I try the example using clang's STL implementation (from
debian package libc++-dev) it builds *and runs* as expected:

clang++ -std=c++11 -stdlib=libc++ string.cc -o string && ./string
(outputs "Some new string")

I am not sure how to continue from here - this might be a bug in clang's
or gcc's std::string implementation, unportable usage from upstream, or
any number of other things.  If you have access to other compilers, it
may help to test the snippet on them too and report the results.

For reference:

$ g++ -dumpversion

-> Does not compile, cannot convert const_iterator->iterator
-> libstdc++-5-dev 5.3.1-5

$ clang++ -dumpversion

-> Does not compile with default/gcc STL implementation
-> Compiles and runs with libc++-dev 3.7.0-1

I hope this helps in resolving this, or at least in figuring out *where*
the issue actually is located.

- Danny

[1]: http://www.cplusplus.com/reference/string/string/insert/
[2]: http://en.cppreference.com/w/cpp/string/basic_string/insert
#include <string>
#include <iostream>

using namespace std;

int main(){
	string s = "Somestring";
	string::const_iterator ci = s.cbegin()+4;
	initializer_list<char> il = { ' ', 'n', 'e', 'w' , ' ' };
	s.insert(ci, il);
	cout << s << endl;
	return 0;

Reply to: