354

Shall this be the example:

#include <iostream>
using namespace std;

int main()
{
    cout << "Hola, moondo.\n";
}

It throws the error:

gcc -c main.cpp gcc -o edit main.o  main.o: In function `main':
main.cpp:(.text+0xa): undefined reference to `std::cout'
main.cpp:(.text+0xf): undefined reference to `std::basic_ostream<char,std::char_traits<char> >& std::operator<< <std::char_traits<char>>(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
main.o: In function `__static_initialization_and_destruction_0(int,int)':
main.cpp:(.text+0x3d): undefined reference to `std::ios_base::Init::Init()'
main.cpp:(.text+0x4c): undefined reference to `std::ios_base::Init::~Init()' collect2: error: ld
returned 1 exit status make: *** [qs] Error 1

Also, this example:

#include <iostream>

int main()
{
    std::cout << "Hola, moondo.\n";
}

throws the error:

gcc -c main.cpp gcc -o edit main.o  main.o: In function `main':
main.cpp:(.text+0xa): undefined reference to `std::cout'
main.cpp:(.text+0xf): undefined reference to `std::basic_ostream<char,std::char_traits<char> >& std::operator<<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char> >&, char const*)'
main.o: In function `__static_initialization_and_destruction_0(int,int)': main.cpp:(.text+0x3d): undefined reference to `std::ios_base::Init::Init()'
main.cpp:(.text+0x4c): undefined reference to `std::ios_base::Init::~Init()' collect2: error: ld
returned 1 exit status make: *** [qs] Error 1

Note: I am using Debian 7 (Wheezy).

9
  • 331
    Try g++ instead of gcc. gcc is for C and will not give you access to the C++ standard library. Commented Jan 30, 2015 at 13:21
  • 4
    Well, that definitely solved the problem. As I understand, GCC is the acronym for Gnu Compiler Collection. Shouldn't it call the g++ compiler when needed? So the command gcc calls the c compiler instead... Commented Jan 31, 2015 at 14:42
  • 5
    @D1X it's because you invoked the linker separately from the compiler. when you write gcc -o edit main.o it doesn't know that main.o is going to need C++ startup libraries. Commented Feb 26, 2015 at 4:22
  • 6
    RTFM gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html Commented Jun 4, 2015 at 14:11
  • 5
    Q: Shouldn't it call the g++ compiler when needed? A: No more than gcc should call gfortran, gjc, ... etc. etc. as needed. Commented Jul 16, 2015 at 3:29

6 Answers 6

489

Compile the program with:

g++ -Wall -Wextra -Werror -c main.cpp -o main.o
     ^^^^^^^^^^^^^^^^^^^^ <- For listing all warnings when your code is compiled.

as cout is present in the C++ standard library, which would need explicit linking with -lstdc++ when using gcc; g++ links the standard library by default.

With gcc, (g++ should be preferred over gcc)

gcc main.cpp -lstdc++ -o main.o
Sign up to request clarification or add additional context in comments.

5 Comments

Why is -Werror needed? I have revised the documentation and if I understand well will make the warnings errors and will make my projects less easy to compile.
@D1X: Because there's a nasty habit among programmers to ignore warnings. Virtually everything that -Wall and even -Wextra warn about is either a very real problem, or sloppy coding that can very easily be fixed. The message here is to get into a habit where you consider compiler warnings a helpful pointer to where your code could be improved, instead of a nuisance. There are hundreds of questions here on SO that wouldn't have been necessary in the first place if the OP had used -Wall -Wextra. -Werror is simply reinforcing that.
@shauryachats, re:"g++ should be preferred over gcc" Is the exception that you may prefer gcc because it compiles .c files as C and .cpp files as C++, whereas g++ will compile both file types as C++? So, you might have institutional conventions or practical reasons (maybe speed?) for preferring your .c files to compile as C rather than as C++?
I was having a very similar problem with an application built by someone else. This solution helped me immensely. In my case, they were using cmake to setup the compile operations, so to the end of the cmake command I needed to add: -DCMAKE_EXE_LINKER_FLAGS="-lstdc++".
For those (like me) wondering why use g++ instead of gcc: stackoverflow.com/a/172592/1169233
87

Yes, using g++ command worked for me:

g++ my_source_code.cpp

2 Comments

then run with ./a.out
This worked for me, I was using gcc and getting the error.
11

Assuming code.cpp is the source code, the following will not throw errors:

make code
./code

Here the first command compiles the code and creates an executable with the same name, and the second command runs it. There is no need to specify g++ keyword in this case.

1 Comment

This works. How? I would have expected this to fail; to require a Makefile.
7

Makefiles

If you're working with a makefile and you ended up here like me, then this is probably what you're looking or:

If you're using a makefile, then you need to change cc as shown below

my_executable : main.o
    cc -o my_executable main.o

to

CC = g++

my_executable : main.o
    $(CC) -o my_executable main.o

5 Comments

You should use $(CXX) for the c++ compiler in Make.
Aren't make files dependent on a TAB character? There aren't any in the Markdown source in this answer. At least it could be mentioned (if it is the case).
@unDeadHerbs That's a good point, yes, you should.
@PeterMortensen It's common knowledge that you need to use the literal tab character in make, I don't know how to insert tab characters into markdown, but you're more than welcome to fix it if you can
@iggy12345: A TAB character can be pasted into the Markdown source. It is preserved (not converted), but it is rendered as spaces on the web page (thus probably too subtle to be useful).
3

Adding the following line in your CMake makes gcc link with std and therefore recognize std::cout

target_link_libraries(your_project
        PRIVATE
        -lstdc++
        )

Comments

0

FWIW, if you want a makefile, here is how you can do either answer by switching the compiler at the top.

# links stdc++ library by default
# CC := g++
# or
CC := cc

all: hello

util.o: util.cc
        $(CC) -c -o util.o  util.cc

main.o: main.cc
        $(CC) -c -o main.o  main.cc

# notice -lstd++ is after the .o files
hello: main.o util.o
        $(CC) -o hello main.o util.o -lstdc++

clean:
        -rm util.o main.o hello

2 Comments

Aren't make files dependent on a TAB character? There aren't any in the Markdown source in this answer. At least it could be mentioned (if it is the case).
it was spaced over to make it into format for viewing as a code block in the markdown. If you know how to edit it so it looks like code and yet has makefile tabs, i would appreciate it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.