This question already has answers here:
C++ Header Files, Code Separation
(4 answers)
Closed 7 years ago.
Consider following two programs.
p1.cpp
#include <iostream>
struct test
{
void fun();
};
int main()
{
test t;
t.fun();
}
p2.cpp
#include <iostream>
void test::fun()
{
std::cout<<"fun() is called\n";
}
I am compiling like following.
g++ -c -o p1.o p1.cpp
g++ -c -o p2.o p2.cpp <--------- This gives me compiler error.
How can I solve this error? What I am doing wrong?
Essentially, you need to:
Create a new file test.h
Move your struct test { ... }; into the file test.h
Add `#include "test.h" to both of your source files.
Recompile both files.
You may want to consider using a makefile to compile your files, and add a dependency on test.h to p1.cpp and p2.cpp, so that these get recompiled when you modify test.h
Related
This question already has answers here:
multiple definition error c++
(2 answers)
Closed 1 year ago.
I am getting error:
/usr/bin/ld: /tmp/ccCbt8ru.o: in function `some_function()':
Thing.cpp:(.text+0x0): multiple definition of `some_function()'; /tmp/ccc0uW5u.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
when building a program like this:
main.cpp
#include "common.hpp"
#include "Thing.hpp"
int main() {
some_function();
}
common.hpp
#pragma once
#include <iostream>
void some_function() {
std::cout << "something" << std::endl;
}
Thing.hpp
#pragma once
class Thing {
public:
void do_something();
};
Thing.cpp
#include "Thing.hpp"
#include "common.hpp"
void Thing::do_something() {
some_function();
}
I'm compiling with: g++ main.cpp Thing.cpp -o main.out
I've also tried using include guards instead of #pragma once, but it didn't seem to work either. Is there something I am forgetting here?
#pragma once and include guards can only prevent multiple definitions in a single translation unit (a .cpp file). The individual units know nothing about each other, and so cannot possibly remove the multiple definition. This is why when the linker links the object files, it sees the multiple definitions still.
To solve this issue, change common.hpp to:
#pragma once
void some_function();
This tells the compiler that there is some code for some_function.
Then, add a file common.cpp that contains the code for the common.hpp header:
#include "common.hpp"
#include <iostream>
void some_function() {
std::cout << "something" << std::endl;
}
Finally, change the g++ command to:
g++ main.cpp common.cpp Thing.cpp -o main
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 1 year ago.
I am writing a simple program to compile from the command prompt. There is an app1 program that uses a class located in a separate file. The class sample1 has a header file sample1.h where all the function declarations exist. The sample1.cpp file contains the function definitions.
app1.cpp:
#include <iostream>
#include "sample1.h"
using namespace std;
int main()
{
sample1 t;
cout<<"The program is ending"<<endl;
return 0;
}
sample1.h:
#ifndef SAMPLE1_H
#define SAMPLE1_H
class sample1
{
public:
sample1();
};
#endif
sample1.cpp:
#include<sample1.h>
#include <iostream>
using namespace std;
sample1::sample1()
{
cout<<"This error sucks"<<endl;
}
I am compiling this program using Windows Subsystem for Linux. However, when I try to compile with g++ 'app1.cpp' -o app1, I get this error:
I get that the error is telling me that the program cannot find the constructor sample::sample() but why is that? I included the header file in the program. These 3 files all exist in the same folder.
You have to compile all your .cpp files (sample1.h is included by preprocessor from information in app1.cpp only):
g++ app1.cpp sample1.cpp -o app1
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.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
The project has 2 classes - Tree and TreeTest class
The TreeTest class tests the functions of Tree class.
TreeTest.h
#ifndef TREETEST_H
#define TREETEST_H
class TreeTest
{
public:
TreeTest();
virtual ~TreeTest();
void InitTreeFunctionTest();
protected:
private:
};
#endif // TREETEST_H
TreeTest.cpp
#include "TreeTest.h"
#include "Tree.h"
#include <cstring>
#include <iostream>
using namespace std;
void TreeTest::InitTreeFunctionTest()
{
//code goes here
}
Main.cpp
#include <iostream>
#include <Tree.h>
#include <TreeTest.h>
using namespace std;
int main(int argc, char* argv[])
{
TreeTest* tt;
tt->InitTreeFunctionTest();
}
But it gives the following error when I compile using
g++ -fprofile-arcs -ftest-coverage main.cpp -I<full path to library> -o test
undefined reference to `TreeTest::InitTreeFunctionTest()'
Can anyone please help me find the error?
Thanks
You have not compiled TreeTest.cpp
Try adding it to your command line:
g++ -fprofile-arcs -ftest-coverage TreeTest.cpp main.cpp -I<full path to headers> -o test
edit:
You will also need to provide the definitions of the constructor and destructor in TestTree.cpp
The other solution is to inline the function definition in the header. But, you probably want to compile it unless the functions are trivial.
Please use #include "TreeTest.h", not #include <TreeTest.h>. If you want to use #include <TreeTest.h>, first, you must make your TreeTest.cpp into a static library. BTW, you can search for the difference between #include "" and #include <>. I hope this can help you.
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