Error when compiling some simple c++ code

Normally this sort of failure happens when compiling your C++ code by invoking the C front-end. The gcc you execute understands and compiles the file as C++, but doesn’t link it with the C++ libraries. Example:

$ gcc example.cpp 
Undefined symbols for architecture x86_64:
  "std::cout", referenced from:
      _main in ccLTUBHJ.o
  "std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from:
      _main in ccLTUBHJ.o
  "std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from:
      _main in ccLTUBHJ.o
  "std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))", referenced from:
      _main in ccLTUBHJ.o
  "std::ios_base::Init::Init()", referenced from:
      __static_initialization_and_destruction_0(int, int)in ccLTUBHJ.o
  "std::ios_base::Init::~Init()", referenced from:
      ___tcf_0 in ccLTUBHJ.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
$ g++ example.cpp 
$ 

As you can see, using g++ makes the problems go away. The same behaviour (with slightly different messages) occurs if you use clang (which I’d recommend):

$ clang example.cpp 
Undefined symbols for architecture x86_64:
  "std::ios_base::Init::~Init()", referenced from:
      ___cxx_global_var_init in cc-IeV9O1.o
  "std::ios_base::Init::Init()", referenced from:
      ___cxx_global_var_init in cc-IeV9O1.o
  "std::cout", referenced from:
      _main in cc-IeV9O1.o
  "std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from:
      _main in cc-IeV9O1.o
  "std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from:
      _main in cc-IeV9O1.o
  "std::ostream::operator<<(std::ostream& (*)(std::ostream&))", referenced from:
      _main in cc-IeV9O1.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
$ clang++ example.cpp 
$

As you can see in the clang error message, you could use -v to see the linker invocation to see what’s going wrong. It would show you this link line:

"/usr/bin/ld" -demangle -dynamic -arch x86_64 
    -macosx_version_min 10.6.8 -o a.out -lcrt1.10.6.o
    /var/folders/zl/zlZcj24WHvenScwjPFFFQE+++TI/-Tmp-/cc-hdOL8Z.o
    -lSystem /Developer/usr/bin/../lib/clang/3.0/lib/darwin/libclang_rt.osx.a

Or something like it – as you can see, it’s linking the C runtime, not C++, and also doesn’t have the C++ libraries. Using clang++ the link line is:

"/usr/bin/ld" -demangle -dynamic -arch x86_64
     -macosx_version_min 10.6.8 -o a.out -lcrt1.10.6.o 
     /var/folders/zl/zlZcj24WHvenScwjPFFFQE+++TI/-Tmp-/cc-wJwxjP.o 
     /usr/lib/libstdc++.6.dylib -lSystem
     /Developer/usr/bin/../lib/clang/3.0/lib/darwin/libclang_rt.osx.a

As you can see, libstdc++ is included, and presto – no link errors.

Leave a Comment