Error "undefined reference to 'std::cout'"
Asked Answered
M

6

342

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).

Murray answered 30/1, 2015 at 13:20 Comment(8)
Try g++ instead of gcc. gcc is for C and will not give you access to the C++ standard library.Erastus
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...Murray
@Murray 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.Prickle
RTFM gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.htmlVolkslied
Q: Shouldn't it call the g++ compiler when needed? A: No more than gcc should call gfortran, gjc, ... etc. etc. as needed.Cabalism
And if using clang instead of gcc, try with clang++ instead.Trimerous
Isn't it "Hola, mundo"? Is Portuguese different?Rosemaria
What is the canonical question for this? The confusion with the two executables g++ and gcc must have been one of the very first questions in 2008.Rosemaria
A
470

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
Abbie answered 30/1, 2015 at 13:22 Comment(11)
It can be used to compile C++ code, the thing is that it doesn't link with the C++ library. gcc will work just fine if you just add -lstdc++.Hooke
Please always include -Wall when giving gcc/g++ command line examples - it helps to get noobs into good habits at an early stage and saves everyone time time further down the road. ;-)Phylogeny
You might want to toss in -Wextra as well for good measure. I am not sure about the edit though, because g++ is to be preferred over gcc -lstdc++...Kif
since we are here, why not do it right to the end: add a -WerrorEsta
Since when is iostreams and std::cout part of the Standard Template Library?Colier
@Colier Since SGI's STL became conflated with the standard library?Morphology
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.Murray
@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.Kif
@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++?Intervalometer
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++".Baur
For those (like me) wondering why use g++ instead of gcc: https://mcmap.net/q/23242/-what-is-the-difference-between-g-and-gccXanthochroism
H
82

Yes, using g++ command worked for me:

g++ my_source_code.cpp
Haply answered 10/7, 2015 at 3:52 Comment(2)
then run with ./a.outOrva
This worked for me, I was using gcc and getting the error.Krum
D
10

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.

Degenerate answered 30/9, 2020 at 6:12 Comment(0)
M
6

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
Microgroove answered 2/9, 2019 at 20:19 Comment(5)
You should use $(CXX) for the c++ compiler in Make.Ochone
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).Rosemaria
@Ochone That's a good point, yes, you should.Microgroove
@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 canMicrogroove
@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).Rosemaria
S
2

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

target_link_libraries(your_project
        PRIVATE
        -lstdc++
        )
Splenetic answered 16/5, 2022 at 20:1 Comment(0)
A
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
Androclinium answered 25/2, 2022 at 20:52 Comment(2)
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).Rosemaria
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.Androclinium

© 2022 - 2024 — McMap. All rights reserved.