doctest: Undefined reference of `operator<<(ostream&, const string&)` when compiling with clang 10 and libc++ 10 on Ubuntu 16.04.6 LTS

Description

I tried to compile a minimal Doctest example of two files on Ubuntu 16.04.6 LTS with clang 10 and libc++ 10, which resulted in link errors.

I assume it’s because <iosfwd> is included without <iostream>, and some_ostream << some_string; compiles, while yielding wrong ABI,

Steps to reproduce

Create two files:

// a.cpp
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

and

// b.cpp
#include <string>
#include "doctest.h"

void foo() {
    std::string a, b;
    CHECK(a == b);
}

and run clang++-10 -O2 -stdlib=libc++ -std=c++17 a.cpp b.cpp. I expected the example to compile, but it resulted in

/tmp/b-c494e1.o: In function `doctest::String doctest::detail::stringifyBinaryExpr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)':
b.cpp:(.text._ZN7doctest6detail19stringifyBinaryExprINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEES8_EENS_6StringERKT_PKcRKT0_[_ZN7doctest6detail19stringifyBinaryExprINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEES8_EENS_6StringERKT_PKcRKT0_]+0x23): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)'
b.cpp:(.text._ZN7doctest6detail19stringifyBinaryExprINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEES8_EENS_6StringERKT_PKcRKT0_[_ZN7doctest6detail19stringifyBinaryExprINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEES8_EENS_6StringERKT_PKcRKT0_]+0x5e): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Extra information

If I add #include <iostream> on top of b.cpp, it compiles successfully.

Strictly speaking, <iosfwd> does not define any operations on ostream, but <string> does. So I’m not sure if this is an issue with doctest not including <iostream> or libc++ including <string> without all necessary dependencies.

  • doctest version: v2.3.7
  • Operating System: Ubuntu 16.04.6 LTS
  • Compiler+version: clang version 10.0.0-++20200412072846+50d7e5d5e7d-1~exp1~20200412053445.132

I’ve used clang and libc++ from apt.llvm.org (sudo apt install clang-10 libc++-10-dev libc++abi-10-dev libc++1-10 libc++abi1-10), and doctest 2.3.7:

clang version 10.0.0-++20200412072846+50d7e5d5e7d-1~exp1~20200412053445.132 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 2
  • Comments: 15 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Looks like it was already reported to libc++ almost a year ago: Bug 41563 - operator<<(ostream, string) declared in <string> but defined in <ostream>. I’ve bumped the thread.

UPD: actually, there is no mention whether this is a libc++ bug or feature.

closing this - will release an official version soon!

@onqtam Thank you, it fixes the original issue for me (at least with Clang 12 on Ubuntu 20.04.3 LTS; I was able to reproduce it with a384864346f48c7ff5608051c176e7bd505712ae and fix with b59552dc43c4e68f58f0ab4163b5d8f5f9e28837) and my student (Apple Clang).

@h5rdly well you could disable the console colors for now by defining DOCTEST_CONFIG_COLORS_NONE globally. I think this should be spun as a separate issue - I bet there’s a trivial fix but I just don’t have the setup to debug & experiment locally…

@h5rdly I think that’s a separate issue - it cannot find isatty and I’m clueless as to why…

Last time I tried to get clang to work on Windows was 2 years ago. We have some clang builds on Windows in our CI: https://github.com/onqtam/doctest/actions/runs/88442907 (and even one of them is currently failing because of some header incompatibility between the STL and clang it seems).

I’m open for PRs 😃

I’ve an issue with Clang 10 as well on Windows. Not sure if it’s a separate ticket though.

For the tutorial code in test.cpp:

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }

TEST_CASE("testing the factorial function") {
    CHECK(factorial(1) == 1);
    CHECK(factorial(2) == 2);
    CHECK(factorial(3) == 6);
    CHECK(factorial(10) == 3628800);
}

With clang++ -o test.exe test.cpp, I get:

# clang++ -o test.exe test.cpp
test-94ae87.o : error LNK2019: unresolved external symbol fileno referenced in function "void 
__cdecl doctest::`anonymous namespace'::color_to_stream(class std::basic_ostream<char,struct 
std::char_traits<char> > &,enum A0xEEF7E3AD::Color::Enum)" (?color_to_stream@?
A0xEEF7E3AD@doctest@@YAXAEAV?$basic_ostream@DU?
$char_traits@D@std@@@std@@W4Enum@Color@1@@Z) test-94ae87.o : error LNK2019: 
unresolved external symbol isatty referenced in function "void __cdecl doctest::`anonymous 
namespace'::color_to_stream(class std::basic_ostream<char,struct std::char_traits<char> > &,enum 
A0xEEF7E3AD::Color::Enum)" (?color_to_stream@?A0xEEF7E3AD@doctest@@YAXAEAV?
$basic_ostream@DU?$char_traits@D@std@@@std@@W4Enum@Color@1@@Z) 
test.exe : fatal error LNK1120: 2 unresolved externals
clang++: error: linker command failed with exit code 1120 (use -v to see invocation)

I’m on Windows 10 64 bit, my clang --version details:

clang version 10.0.0
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin