Separate header file and its logic in c++ [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
Please make me understand how header files works in C++. I am using osx and g++ compiler. I have
main.cpp
#include<iostream>
#include "myfunc.hpp"
using namespace std;
int main() {
square(10);
return 0;
}
myfunc.hpp
#ifndef MYFUNC_HPP_
#define MYFUNC_HPP_
/*
void square(int x) {
std::cout << x * x << std::endl;
};
*/
void square(int);
#endif // MYFUNC_HPP_
myfunc.cpp
#include<iostream>
#include "myfunc.hpp"
using namespace std;
void square(int x) {
cout << x * x << endl;
}
Now when I am trying to compile using g++ main.cpp , its giving
Undefined symbols for architecture x86_64:
"square(int)", referenced from:
_main in main-088331.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Because it is not able to find the function definition of square that is defined in myfunc.cpp.
But, if I defined square function in header file, it works because now it finds the function definition.
I want to use the function defined in myfunc.cpp in main.cpp, so I am using the header file myfunc.hpp. How can I achieve this? Am I doing something wrong here? Maybe my concept is not that clear about headers since I am new to C++ programming.

When you call g++ main.cpp, the compiler will try to compile and link the program, yet for linking, it lacks the source- or object file containing the definition of square. So it could compile main.cpp based on the function prototype given in the header file, yet it cannot link then.
To just compile main.cpp write
g++ -c main.cpp
To compile and link the complete program write:
g++ main.cpp myfunc.cpp
For more details concerning programs comprising several translation units confer, for example, this link.

Related

Error: Multiple definitions of function in C++ class [duplicate]

This question already has answers here:
Separating class code into a header and cpp file
(8 answers)
Closed 5 months ago.
I don't know how to add functions of a class outside its scope to it, use them in another class and then compile it.
MyMain.cpp
#include"MyClass.cpp"
int main(){
MyClass myClass;
myClass.run();
}
MyClass.cpp
#ifndef MYCLASS_CPP
#define MYCLASS_CPP
#include<iostream>
class MyClass {
private:
void usage();
public:
void run();
};
void MyClass::usage(){
std::cout << "usage called" << std::endl;
}
void MyClass::run(){
usage();
}
#endif
I try to compile it with:
g++ MyMain.cpp MyClass.cpp -o main
With that I get the following error message:
/usr/bin/ld: /tmp/ccN7GfOD.o: in function `MyClass::usage()':
MyClass.cpp:(.text+0x0): multiple definition of `MyClass::usage()'; /tmp/ccLhxS6v.o:MyMain.cpp:(.text+0x0): first defined here
/usr/bin/ld: /tmp/ccN7GfOD.o: in function `MyClass::run()':
MyClass.cpp:(.text+0x38): multiple definition of `MyClass::run()'; /tmp/ccLhxS6v.o:MyMain.cpp:(.text+0x38): first defined here
collect2: error: ld returned 1 exit status
If I have understood the concept correctly, the function headers within the class serve only as placeholders. The actual functionality is then "overwritten" by the external functions, which also contain a body.
And why does the error message say, that the function is already defined in the MyMain.cpp?
I have also seen that there are many similar questions here, but unfortunately I could not expand my understanding of the basic problem to solve it.
Is it possible that I am using the command to build the class with C++ incorrectly or that I can save the #include "MyClass.cpp"?
Kind regards
Several things wrong. here's the steps to put it right
Rename MyClass.cpp to MyClass.h.
Create a new empty file MyClass.cpp
Move the function definitions MyClass::usage() { .. } and MyClass::run() { .. } from MyClass.h to MyClass.cpp. You should probably also move #include <iostream> but this is not essential.
Add #include "MyClass.h" to MyClass.cpp
Change #include "MyClass.cpp" to #include "MyClass.h" in MyMain.cpp
Then build as you are doing now. That part is correct.
Essentially the technique is to separate your code into declarations and definitions. The declarations go into header files, which are included in the cpp files. The cpp files contain the definitions and are what you compile.

Xcode: linker command failed with exit code 1 (use -v to see invocation) [C++]

I am running a c++ programs with multiple files (2)
goofing_around.cpp
add.cpp
goofing_around.cpp:
//
// goofing_around.cpp
// new
//
// Created by Chirag Maheshwari on 14/08/18.
// Copyright © 2018 Chirag Maheshwari. All rights reserved.
//
#include <iostream>
int add(int x,int y);
int doubleNumber(int n)
{
return 2*n ;
}
int main()
{
int x;
std::cout << "Enter the number to be doubled: ";
std::cin >> x;
std::cout << doubleNumber(x)<<std::endl;
std::cout << add(3,2) << std::endl;
return 0;
}
add.cpp:
#include <iostream>
int add(int x,int y){
return x+y;
}
And yet I get an error which goes like this:
duplicate symbol _main in:
/Users/chirag/Library/Developer/Xcode/DerivedData/new-hapneuayvrpdonefrpnervwkxysx/Build/Intermediates.noindex/new.build/Debug/new.build/Objects-normal/x86_64/goofing_around-5915963FFFEE024.o
/Users/chirag/Library/Developer/Xcode/DerivedData/new-hapneuayvrpdonefrpnervwkxysx/Build/Intermediates.noindex/new.build/Debug/new.build/Objects-normal/x86_64/goofing_around-93C433489854664D.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Edit: This was weird.The error was there even before I added the add.cpp file.But then I deleted the projects and tried again.And after rewriting all the code,and adding the add file,I deleted the .h file.But only this time it worked,with the exact same code,and including the same function prototype.I did not have to include the add.cpp files either.
Super weird,but does anyone know why?
The problem is that you are not linking well the add method. You have implemented it in add.cpp but you don't add the link to it in the main code. You should include another "include" in goofing_around.cpp, something like
#include "add.cpp";
It should work.
Another observation: there is no need to print the name of the method "add" in the main code, since these things are done in the header files (if you have any). If not, there no sense to write that since you can just link your main code to the add.cpp.

How to compile a C++ program via Terminal Mac

I have a question on how to compile a C++ program in Terminal Mac. My program has a header file and a main file. I know that I can't compile both the header file and the main file. and just to compile the main file. I also know that I need to create a name for storing the compiled file. Here is my compile command that I used g++ -o execute1 main.cpp and I get this:
Undefined symbols for architecture x86_64:
"add(int, int)", referenced from:
_main in main-f2nZvj.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
How can I fix this? Any help will be greatly appreciated. If it helps, below is my code for the two files:
add.h:
int add(int x, int y);
main.cpp:
#include <iostream>
#include "add.h"
int main(){
using namespace std;
cout << "The sum of 9 and 9 is " << add(9, 9) << endl;
return 0;
}
You need an add.cpp file that implements your add() function, then you can compile the whole thing as:
$ g++ -Wall main.cpp add.cpp -o execute1
This line:
int add(int x, int y);
in your add.h just tells the compiler that somewhere, there's a function called add that takes two integers and returns an integer. Having this and this alone will let the compiler leave you alone when you use this add function in files that #include "add.h". The compiler doesn't have to know exactly what the function does, it just needs to know what parameters it accepts and what the function returns. It doesn't bother looking for the function body until it actually goes to compile the function.
In order for this to properly compile, you need to include a function body for your add function in add.cpp. Even just this will work:
int add(int x, int y) {
return 1;
}
This will allow the program to compile because now the compiler know what code it's supposed to execute when it gets to your call to the add function within main.
This will work, as a minimum, as a placeholder until you're ready to actually write the exact logic you want this function to contain. But until this function body exists, you won't be able to compile (unless you remove all the other references to the function).

C++ compiler issue (?): can't pass arguments to functions in separate class files [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
I recently started working on an interpreter in C++, but I got annoyed that vectors or arrays could not be passed to external class methods no matter what I tried and so I deleted everything I had worked on. As it turns out, I can't pass even an int to another class. I decided to give C++ another chance before resorting to C or Java, but the compiler still doesn't work as I would expect. Maybe I'm forgetting something simple about C++, as I haven't used it in a while, but this seems simple enough. My problem is: I can't pass arguments to methods in other classes when they're not defined in the same file. Here's what I'm trying to do:
Main: main.cpp
#include "myclass.h"
int main() {
MyClass test;
int n = test.add(25, 30);
return n;
}
Header: myclass.h
class MyClass {
public:
int add(int a, int b);
};
Class implementation: myclass.cpp
#include "myclass.h"
int MyClass::add(int a, int b) {
return a + b;
}
Compiling this with g++ main.cpp yields
/tmp/ccAZr6EY.o: In function main':
main.cpp:(.text+0x1a): undefined reference toMyClass::add(int, int)'
collect2: error: ld returned 1 exit status
What the heck am I doing wrong? Also, the compiler yells at me for the same thing even if my functions aren't parameterized, so it must be a problem with the header.
Any help is much appreciated - thanks!
You need to compile both files
g++ main.cpp myclass.cpp
If you only compile main.cpp, the compiler finds the declaration of MyClass::add in your header but the linker later fails to find an implementation of MyClass::add to jump to.

Undefined symbols for architecture i386:

I've recently moved over to a mac, and am struggling using the command line compilers. I'm using g++ to compile, and this builds a single source file fine. if I try to add a custom header file, when I try to compile using g++ I get undefined symbols for architecture i386. The programs compile fine in xCode however. Am I missing something obvious?
tried using g++ -m32 main.cpp... didn't know what else to try.
Okay, The old code compiled... Have narrowed it down to my constructors.
class Matrix{
public:
int a;
int deter;
Matrix();
int det();
};
#include "matrix.h"
Matrix::Matrix(){
a = 0;
deter = 0;
}
int Matrix::det(){
return 0;
}
my error is
Undefined symbols for architecture x86_64:
"Matrix::Matrix()", referenced from:
_main in ccBWK2wB.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
my main code has
#include "matrix.h"
int main(){
Matrix m;
return 0;
}
along with the usual
It looks like you’ve got three files:
matrix.h, a header file that declares the Matrix class;
matrix.cpp, a source file that implements Matrix methods;
main.cpp, a source file that defines main() and uses the Matrix class.
In order to produce an executable with all symbols, you need to compile both .cpp files and link them together.
An easy way to do this is to specify them both in your g++ or clang++ invocation. For instance:
clang++ matrix.cpp main.cpp -o programName
or, if you prefer to use g++ — which Apple haven’t updated in a while, and it looks like they won’t in the foreseeable future:
g++ matrix.cpp main.cpp -o programName
is not the case here, but it may happen to be the you forget to put the class name with ::
for example:
a good format:
foo.h
class Foo{
public:
Foo();
void say();
private:
int x;
};
foo.cpp
Foo::Foo(){
this->x = 1;
}
void Foo::say(){
printf("I said!\n");
}
a bad format
foo.h
class Foo{
public:
Foo();
void say();
private:
int x;
}
foo.cpp
Foo::Foo(){
this->x = 1;
}
//I always mistake here because I forget to put the class name with :: and the xcode don't show this error.
void say(){
printf("I said!\n");
}
Did you actually define the Box constructor somewhere? (like Line.cpp)