Quick C++ question for C++ experts :)

Jonathan Wakely jwakely at redhat.com
Wed Apr 1 13:32:24 UTC 2015


On 28/03/15 16:45 -0300, Paulo César Pereira de Andrade wrote:
>2015-03-28 16:06 GMT-03:00 Paulo César Pereira de Andrade
><paulo.cesar.pereira.de.andrade at gmail.com>:
>> Is this expected to not compile with -fno-implicit-templates?
>>
>> ---%<---
>> $ cat test.cc
>> #include <string>
>> std::string test(int i)
>> {
>>     std::string t;
>>     std::string s = "(";
>>     t = "";
>>     for (int r = i; r; r>>=1) {
>>         if (r & 1)
>>             t = "1" + t;
>>         else
>>             t = "0" + t;
>>     }
>>     s += t;
>>     s += ")";
>>     return s;
>> }
>>
>> int
>> main(int argc, char *argv[])
>> {
>>     std::string s = test(16);
>>     return 0;
>> }
>>
>> $ g++ -fno-implicit-templates test.cc
>> /tmp/ccai7t5T.o: In function `test(int)':
>> test.cc:(.text+0x9d): undefined reference to
>> `std::__cxx11::basic_string<char, std::char_traits<char>,
>> std::allocator<char> > std::operator+<char, std::char_traits<char>,
>> std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
>> std::char_traits<char>, std::allocator<char> > const&)'
>> test.cc:(.text+0xd9): undefined reference to
>> `std::__cxx11::basic_string<char, std::char_traits<char>,
>> std::allocator<char> > std::operator+<char, std::char_traits<char>,
>> std::allocator<char> >(char const*, std::__cxx11::basic_string<char,
>> std::char_traits<char>, std::allocator<char> > const&)'
>> collect2: error: ld returned 1 exit status
>> ---%<---

As I stated in the bug report, the code is invalid, but used to work
due to an undocumented "accidental" feature of libstdc++.so which
happens to provide instantiations of the required operator+().

If you use -fno-implicit-templates then it is your responsibility to
instantiate all the templates you use. The program uses operator+()
without instantiating it, so the program is wrong. (It also uses a
number of other templates without instantiating them, which is also
wrong).

>  I will open a gcc bug report. It must be a bug, because if using
>a temporary to convert "1" or "0" to a std::string it works. Or,
>explicit converting, e.g.:
>
>-        t = "1" + t;
>+        t = std::string("1") + t;

This just happens to work because it uses a different overload of
operator+ that is defined inline, so the compiler inlines the code and
doesn't require an instantiation.

Using -fno-implicit-templates in the package is probably a bug IMHO.
The justification in the package's readme is weak.


However, in order not to break such buggy programs which worked (by
accident) previously I have added the relevant instantiations to
libstdc++.



More information about the devel mailing list