<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - operator<<(ostream, string) declared in <string> but defined in <ostream>"
   href="https://bugs.llvm.org/show_bug.cgi?id=41563">41563</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>operator<<(ostream, string) declared in <string> but defined in <ostream>
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>smeenai@fb.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>eric@efcs.ca, ldionne@apple.com, llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>$ cat f.cpp
#include <iosfwd>
#include <string>
void f(std::ostream &os) { os << std::string("Hello world!\n"); }

$ cat main.cpp
#include <iostream>
#include <string>
void f(std::ostream &);
int main() { f(std::cout); }

$ clang++ f.cpp main.cpp
Undefined symbols for architecture x86_64:
  "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&)", referenced
from:
      f(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in
f-e729ff.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The operator<<(ostream, string) overload is declared in <string> but defined in
<ostream>, so if you just include <string>, you end up with an undefined
reference to it which results in a link error, as demonstrated above. It links
successfully if I change f.cpp to include <ostream> instead of <iosfwd>.

I don't know if this would necessarily be considered a bug, but I find it
strange that you can end up in a situation where you include a header and have
all the declarations needed to compile, but then have to pull in another header
to actually be able to link.

My above test case was run with Xcode 10.2, but in theory you should have the
same issue with upstream libc++.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>