DevHeads.net

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

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
---%<---

I am trying to fix a package, but it is documented to
require -fno-implicit-templates and instantiate templates
in one of the sources, but it instantiates templates for
its own types.

Thanks,
Paulo

Comments

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

By =?ISO-8859-1?Q?... at 03/28/2015 - 15:45

2015-03-28 16:06 GMT-03:00 Paulo César Pereira de Andrade
<paulo.cesar.pereira.de. ... at gmail dot com>:
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;

My C++ foo is not that great, thus asking before opening a
bug report.

Thanks,
Paulo

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

By Jonathan Wakely at 04/01/2015 - 09:32

On 28/03/15 16:45 -0300, Paulo César Pereira de Andrade wrote:
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).

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++.

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

By Ian Malone at 04/01/2015 - 10:16

On 1 April 2015 at 14:32, Jonathan Wakely < ... at redhat dot com> wrote:
Do you mind clarifying? I thought <string> should provide that
<a href="http://www.cplusplus.com/reference/string/string/operator+/" title="http://www.cplusplus.com/reference/string/string/operator+/">http://www.cplusplus.com/reference/string/string/operator+/</a> or is that
what fno-implicit-templates is turning off?

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

By Jonathan Wakely at 04/01/2015 - 11:09

On 01/04/15 15:16 +0100, Ian Malone wrote:
Of course string provides it, but it's a template, so it needs to be
instantiated. The GCC manual documents -fno-implicit-templates like
so:

Never emit code for non-inline templates that are instantiated
implicitly (i.e. by use); only emit code for explicit
instantiations.

The invalid program in the OP uses operator+(), which would normally
instantiate the function template implicitly. But if you use
-fno-implicit-templates you are promising the compiler you will
provide explicit instantiations. The program above does not provide
them, so it is broken.

"If you lie to the compiler, it will get its revenge."
-- Henry Spencer

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

By Ian Malone at 04/02/2015 - 05:34

On 1 April 2015 at 16:09, Jonathan Wakely < ... at redhat dot com> wrote:
Thanks. Hadn't occurred to me the + operator here was a template as
I'd never had to deal with basic_string. Still a bit puzzled as
cplusplus.com says string is an instantiation of basic_string while
cppreference.com says it's a typedef (which I guess doesn't count as
explicit instantiation).

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

By Jonathan Wakely at 04/08/2015 - 09:15

On 02/04/15 10:34 +0100, Ian Malone wrote:
cplusplus.com is notoriously inaccurate. It probably means string is a
specialization of basic_string.

This is going very off-topic for this list.