8

I'm trying to compile a library written with C++11 features using GCC 5.1 on Ubuntu. However, it complains std::unique_ptr is not defined.

gcc (Ubuntu 5.1.0-0ubuntu11~14.04.1) 5.1.0
g++ (Ubuntu 5.1.0-0ubuntu11~14.04.1) 5.1.0

CXX flags:

-std=c++11 -Wall -Wextra -Weffc++ -pedantic

Output:

error: ‘unique_ptr’ in namespace ‘std’ does not name a template type
         std::unique_ptr< detail::RegexImpl > m_pimpl;

However, I'm able to compile the exact same code on OSX.

Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)

CXX flags:

-stdlib=libc++ -std=c++11 -Wall -Wextra -Weffc++ -pedantic

What am I doing wrong?

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Thijs
  • 714
  • 9
  • 23
  • 5
    Please show the source. Are you including ``? – Brian Cain Jun 15 '15 at 20:56
  • I had no problem with gcc 5.1 on Ubuntu. I compiled it from source, added the includes and lib path to env variable and it works. – bolov Jun 15 '15 at 20:57
  • 2
    It sounds like you are relying on the implementation-dependent inter-header dependencies. No surprise when non-portable code breaks when you try to port it, luckily the fix is easy. – Ben Voigt Jun 15 '15 at 20:59
  • BTW I'm sad that GCC says the misleading "template type". – Lightness Races in Orbit Jun 15 '15 at 21:00
  • 1
    @LightnessRacesinOrbit Yeah, it would be nicer to see something like "error: 'unique_ptr' in namespace 'std' does not exist" here. That would require some extra work on the part of the GCC devs if the error message is shared between the "does not exist" and the "does exist but is not a template" cases, though. –  Jun 15 '15 at 21:02
  • @hvd: Well just changing it to "template" would be a start :-) – Lightness Races in Orbit Jun 15 '15 at 21:03
  • @LightnessRacesinOrbit Didn't realise that was what you meant. :) Yeah, the standard uses "class template" and "function template". Neither "template type" nor "type template" is a standard term, but "type template" is better in line with the standard's terms. (Or, after your edit, just "template" works too.) –  Jun 15 '15 at 21:07
  • I've reviewed the source, and indeed the include was missing. I assumed it was there because the code compiles fine with Clang. I'm not the author of the library so I can't comment on inter-header dependencies, but is this the cause? – Thijs Jun 15 '15 at 21:08
  • @Thijs Yes. A library header `A` may include library header `B` for pretty much any reason. If you need library header `B`, but only include library header `A`, then it may work on some implementations, and fail on others. And even libc++ has such silently included headers. –  Jun 15 '15 at 21:10
  • @hvd: Yeah plenty of people get confused as to what templates really are, an in part IMO that's because compilers and books and poor tutorials say silly things like "template class" as if that's some magical kind of class. You and I know that that's not the case. If they knew that it instead is a _template_ that makes a class, perhaps they'd have an easier time of it. :) Anyway. – Lightness Races in Orbit Jun 15 '15 at 21:12

1 Answers1

22

You're not doing anything wrong. The library's source is missing an #include <memory>.

This is simply an unfortunate error by the author of the library. It's surprisingly commonplace for people to rely on certain standard headers just so happening to include other standard headers on their particular implementation, without checking that they're using all the #include statements that they should.

You could hack the #include in for now but, long term, you should raise a bug with the library author and maybe even contribute a patch, if the project accepts patches.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Is there a compiler known to use the minimal inclusions necessary? Or is the best strategy for that library's maintainer just to make sure it uses multiple c++ compilers in order to find errors like this one? – Brian Cain Jun 15 '15 at 21:20
  • @BrianCain: I'm not really sure how to answer that, to be perfectly honest. My personal strategy is one of _diligence_: whenever I write a standard library name that I don't absolutely know I've already used in the same translation unit, I look up which header it comes from and I then add the relevant `#include` if it's not already there. Can't really go wrong if you keep that up, though it does get a little tedious after a while. – Lightness Races in Orbit Jun 15 '15 at 21:45
  • Got it! Will submit a patch to the author – Thijs Jun 15 '15 at 21:46
  • @BrianCain: (Of course, that doesn't always work; on the occasion that I forget all steps other than the first, sometimes my build breaks and that's great, but other times it does not and then I have just introduced one of these silent bugs. -.-) – Lightness Races in Orbit Jun 15 '15 at 21:47
  • Thank you so much @LightnessRacesinOrbit. Saved me a lot of debugging. – splintercell May 28 '19 at 08:36