I am a novice programmer in c++, and I am currently getting a compiling error
Undefined symbols for architecture x86_64
Supposedly this originates from how the header files and implementation files are included/coded.
Below is some code that generates the compiling error I am receiving
Main
//Main.cpp
#include <iostream>
#include <string>
#include "Animal.hpp"
using namespace std;
int main(){
Animal myPet;
myPet.shout();
return 0;
}
Header
//Animal.hpp
#ifndef H_Animal
#define H_Animal
using namespace std;
#include <string>
class Animal{
public:
Animal();
void shout();
private:
string roar;
};
#endif
Implementation
//Animal.cpp
#include "Animal.hpp"
#include <string>
Animal::Animal(){
roar = "...";
}
void Animal::shout(){
roar = "ROAR";
cout << roar;
}
This code generates my compiling issue. How would this issue be resolved?
Thanks for your time
EDIT
Undefined symbols for architecture x86_64:
"Animal::shout()", referenced from:
_main in test-5f7f84.o
"Animal::Animal()", referenced from:
_main in test-5f7f84.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
maybe you might want to see an alternative set of your 3 files, where things are a little more "sorted", you know, where things are put at places where they "really" belong to.
So here's the "new" header file ..
//Animal.hpp
#ifndef H_Animal
#define H_Animal
#include <string> // suffices
// Interface.
class Animal {
std::string roar; // private
public:
Animal();
void shout();
};
#endif
then the source file ..
//Animal.cpp
#include "Animal.hpp"
#include <iostream> // suffices
// Constructor.
Animal::Animal()
:
roar("...") // data member initializer
{}
// Member function.
void Animal::shout() {
roar = "ROAR";
std::cout << roar;
}
and the main program ..
//Main.cpp
#include "Animal.hpp"
int main(){
Animal thePet;
thePet.shout(); // outputs: `ROAR'
}
plus a little GNU makefile ..
all: default run
default: Animal.cpp Main.cpp
g++ -o Main.exe Animal.cpp Main.cpp
run:
./Main.exe
clean:
$(RM) *.o *.exe
Kick-off things typing just "make" in your cmd-line. Did you like it? --
Regards, M.
I can only find one error in your code and your compiler should have told you that one.
In Animal.cpp, you are using std::cout but you're not #includeing <iostream>. You #include it in Main.cpp but it is not needed there.
If you (really) want to refer to std::cout as cout in Animal.cpp, you also have to add a using namespace std directive in that file.
The using directive in the header file (Animal.hpp) is evil. Get rid of it and type std::string instead. Putting using directives into headers litters the namespaces of all files that use it.
I also don't understand your intentions with the roar member. What is the point of assigning "..." to it in the constructor and re-assigning "ROAR" to it every time shout is called? Couldn't you do without that variable and simply have
void
Animal::shout()
{
std::cout << "ROAR\n";
}
? I have added a newline because you'd probably want one.
The main issue I was having with this coding project was solved by #JamesMoore.
"#Nicholas Hayden Okay if you have three files, test.cpp(which has main), animal.cpp, and animal.hpp. The command should be g++ animal.cpp test.cpp. You need to compile all source files."
I am currently not using an IDE. So, when I was calling the compiler to compile my main.cpp - It was an issue of compiling the implementation file.
g++ test.cpp
needed to become
g++ test.cpp animal.cpp
This would call the compiler to compile everything the program needed.
Related
I am trying to link a header file which has a class defined in it and a .cpp file that has the actual functions of that class to my main cpp file but I'm getting this error:
c++ DataMembers.cpp -o DataMembers
Undefined symbols for architecture x86_64:
"Cat::eat()", referenced from:
_main in DataMembers-053507.o
"Cat::meow()", referenced from:
_main in DataMembers-053507.o
"Cat::sleep()", referenced from:
_main in DataMembers-053507.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [DataMembers] Error 1
Please note that all files exists in the same directory!
my main.cpp code is:
#include "Cat.h"
#include <iostream>
using namespace std;
int main()
{
Cat myCat;
myCat.eat();
myCat.meow();
myCat.sleep();
}
my Cat.h code:
#ifndef CAT_H_
#define CAT_H_
class Cat
{
public:
void meow();
void sleep();
void eat();
};
#endif
and Cat.cpp code is:
#include <iostream>
#include "Cat.h"
using namespace std;
void Cat::meow()
{
cout << "Meowwwwww!" << endl;
return;
}
void Cat::sleep()
{
cout << "Zzz ... " << endl;
return;
}
void Cat::eat()
{
cout << "Num Nom Nom .. Yummy" << endl;
return;
}
Interesting thing is when I change the header file in my main.cpp from #inclue "Cat.h"
into #include "Cat.cpp" the program compiles without any issues! I just don't know why?
I have searched for a solution but couldn't find any yet! and I need to be able to use header files I create myself!
Thank you in advance friends!
When compiling make sure that you reference all the cpp source files so it can generate the according object files.
It seems like you forgot to reference cat.cpp. The compiler sees that you have a header file included, assuming the implementation of this class will be in another cpp file. Because you forgot to reference the said file, the linker will complain that some undefined symbols cannot be linked.
Once you included the cat.cpp directly into your main.cpp, you basically copied all its contents to this file, which means there is no need anymore to link the implementation from another translation unit.
In short: you need to tell your compiler about cat.cpp
First Check For Which Architecture You Have Written the Header File For, If it is the Same Architecture as the Main File, Then Try Using Full Path From the Drive, Even then It is Not Working, Add Your Header File Path as an Additional Include Directories.
try this in main.cpp
#include "Cat.cpp"
instead of:
#include "Cat.h"
source:
How to create a C++ project in VS Code and link main, functions and header?
In Cat.cpp you wrote #include "cat.h" but the file name is "Cat.h" so you messed up the capitalization.
recently I've started learning c++. When I tried to write my header file, I got include error. Here is my code:
First is the header file(header.h)
#pragma once
void print(int);
and then is its cpp file(header.cpp)
#include "header.h"
#include <iostream>
using namespace std;
void print(int x){
cout << x << endl;
}
and finally my main cpp program(main.cpp)
#include <iostream>
#include "./header.h"
using namespace std;
int main(){
int x = 123;
print(x);
}
Here is the error, I can't figure out what it's saying orz
cd "/Users/yianchen/Desktop/cpp practice/" && g++ main.cpp -o main &&
"/Users/yianchen/Desktop/cpp practice/"main Undefined symbols for
architecture x86_64: "print(int)", referenced from:
_main in main-90c620.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to
see invocation)
I have searched for some solution, when I use
#include "header.cpp"
It works fine, but I see guys unrecommended using #include some_file.cpp
By the way, I use visual studio code and use code runner. Thanks!
The easiest solution would be to do something like the following
g++ header.cpp main.cpp
This will make sure that the function defined in header.cpp is compiled together with the code that uses it.
Normal usage would be to compile header.cpp, not to include it in another .cpp source. Then the linker will put the pieces together.
Trivial as it ought to be, I just cannot figure out how to separate my source code into different files.
My code compiles and executes just fine when it is written as a single source file:
#include <iostream>
using namespace std;
class Greeter{
public:
void greet();
};
void Greeter::greet(){
cout << "Hello World!";
}
int main(){
Greeter greeter;
greeter.greet();
return 0;
}
But try as I might, separating the code into separate source files:
Greeter.h
#include <iostream>
using namespace std;
class Greeter{
public:
Greeter();
void greet();
};
Greeter.cxx
#include <iostream>
#include "Greeter.h"
using namespace std;
void Greeter::greet(){
cout << "Hello World!";
}
main.cxx
#include <iostream>
#include "Greeter.h"
using namespace std;
int main(){
Greeter greeter;
greeter.greet();
return 0;
}
always results in a compilation error:
main.cxx:(.text+0x16): undefined reference to `Greeter::Greeter()'
It is unclear whether the comments solved your problem. In separating your source into a header and multiple sources, your primary problem evidenced by the error is that you include an incomplete constructor for class Greeter in Greeter.h. Specifically, you fail to include "an empty parameter list" to complete the constructor, e.g.
Greeter() {}; /* default construct */
See cppreference - Default constructors
The next issue you should avoid is including using namespace std; in the header file. See “using namespace” in c++ headers. Instead, simply make your call to cout, std::cout and eliminate the need to include the namespace altogether.
Next, while iostream has proper header guards, you only need to include it in Greeter.cpp (that is the only source making use of an iostream function). You should also include header guards in your Greeter.h to prevent multiple inclusions during compilation. Simply create a #define and check whether or not that is already defined within the header, e.g.
greeter.h
#ifndef my_class_greeter_h
#define my_class_greeter_h 1
class Greeter {
public:
Greeter() {}; /* default construct */
void greet();
};
#endif
Now every file that includes greeter.h will avoid including it again if my_class_greeter_h is already defined.
greeter.cpp
Your source file with your class function definition is the only source that relies on an iostream call, and is the only file that requires #include <iostream>, e.g.
#include <iostream>
#include "greeter.h"
void Greeter::greet(){
std::cout << "Hello World!\n";
}
main.cpp
You main.cpp source file need only include your header containing the class definition, e.g.
#include "greeter.h"
int main (void) {
Greeter greeter; /* instantiate greeter */
greeter.greet(); /* call greet() */
return 0;
}
Both Sources Must Be Compiled
Compiling the separate source files requires that both main.cpp and greeter.cpp be compiled (either compiling greeter.cpp to object or by simply including both .cpp files in your compile string).
Compiling With gcc/clang
$ g++ -Wall -Wextra -pedantic -std=c++11 -Ofast -o main main.cpp greeter.cpp
Compiling With VS (cl.exe)
> cl /nologo /W3 /Ox /EHsc /Femain /TP main.cpp greeter.cpp
(do not accept code until it compiles without warning)
Example Use/Output
In either case, the output is as expected:
$ ./main
Hello World!
Look things over and let me know if you have further questions.
This is a minimal program that I made to understand this problem better.
ADT.h
#ifndef ADT_H
#define ADT_H
class ADT {
public:
void print();
};
#endif
ADT.cpp
#include <iostream>
#include "ADT.h"
using namespace std;
void ADT::print()
{
cout << "This program works." << endl;
}
testADT.cpp
#include <iostream>
#include "ADT.h"
using namespace std;
int main(void)
{
ADT sa;
sa.print();
return 0;
}
I compiled it with the vim/minGW compiler my school provided me like so:
g++ testADT.cpp
Which produced the following error:
C:\Users\King\AppData\Local\Tempcc6eoWAP.o:testADT.cpp(.text+0x15 reference to 'ADT::print()'
collect2.exe error: ld returned 1 exit status
Can you explain this error message and indicate the error in my code?
You didn't post the error, but I see that you're missing the semicolon after void print()in the header.
EDIT: That's a linker error. Each source file should be compiled into an object file; then the object files linked:
g++ -c -oADT.o ADT.cpp
g++ -c -otestADT.o testADT.cpp
g++ -oADT ADT.o testADT.o
You can also do it in one line as in michaeltang's answer, but then you can't recompile the sources individually (the 2 step method scales better).
You should also compile ADT.cpp
g++ -o testadt testADT.cpp ADT.cpp
I am working in c++ /ubuntu.
I have:
libr.hpp
#ifndef LIBR
#define LIBR
#include <string>
using namespace std;
class name
{
public:
name();
~name();
std::string my_name;
std::string method (std::string s);
};
#endif
and
libr.cpp
#include <iostream>
#include <string>
#include <stdlib.h>
#include "libr.hpp"
using namespace std;
name::name()
{
}
std::string name::method(std::string s)
{
return ("YOUR NAME IS: "+s);
}
From these two I've created a libr.a.
In test.cpp:
#include <iostream>
#include <string>
#include <stdlib.h>
#include "libr.hpp"
using namespace std;
int main()
{
name *n = new name();
n->my_name="jack";
cout<<n->method(n->my_name)<<endl;
return 0;
}
I compile with g++ and libr.a. I have an error: "name::name() undefined reference", why?
I would like to mention that I've added in qt creator at qmake the .a. When I compile, I have the error. How can I solve it?
This is a linker error, not a compiler error. It means that you have called but you have not defined the constructor. Your allocation name *n = new name(); calls the constructor.
Since you defined the constructor in your libr.cpp, what this means is that this compilation unit is not making its way into your executable. You mentioned that you are compiling with libr.a. When you compile your libr.cpp the result is a .o file, not a .a file.
You are not linking libr.o into your executable.
What are the steps you're using to compile your "project"?
I performed the following steps and managed to build it with warnings/errors.
g++ -Wall -c libr.cpp
ar -cvq libr.a libr.o
g++ -Wall -o libr main.cpp libr.a
One last thing, if I change the order off the last command, like
g++ -Wall -o libr libr.a main.cpp
I get the following error:
Undefined first referenced
symbol in file
name::name() /tmp/cc4Ro1ZM.o
name::method(std::basic_string<char, std::char_traits<char>, std::allocator<char
> >)/tmp/cc4Ro1ZM.o
ld: fatal: Symbol referencing errors. No output written to libr
collect2: ld returned 1 exit status
in fact , you needn't define the destructor yourself because the default destructor will be used when the class calling is over.
and in the VS2008,it's all right!