Now when I try to compile main.cpp, I get an error as Undefined symbol add(int) in module main.cpp Please help me!
//main.cpp
#include<iostream.h>
#include "addition.h"
int main()
{
add(4);
return (0);
}
//add.cpp
#include "addition.h"
#include<iostream.h>
void add(int a)
{
cout<<a<<endl;
}
//addition.h
void add(int a);
The problem is that main() uses add(). And add is defined in another compilation unit (add.cpp) which is why you get the error message Undefined symbol add(int).
You need to tell the compiler to compile both pieces of code and link them together:
The easy way:
g++ main.cpp add.cpp
The long way:
# 1 Make the main object file
g++ -c main.cpp
# 2 Make the add object file
g++ -c add.cpp
# Link the object files into an executable.
g++ main.o add.o
Related
Situation is as follows: I've got a simple project consisting of two files - Calc.h and Calc.cpp.
Calc.h:
#pragma once
class Calc {
public:
int add(int,int);
static const int a = 42;
}
Calc.cpp:
#include "Calc.h"
class Calc {
public:
int add(int a,int b){
return a + b;
};
}
CalcTestSuite.h:
#pragma once
#include "Calc.h"
#include <cxxtest/TestSuite.h>
class CalcTestSuite : public CxxTest::TestSuite {
public:
void testAddition(void)
{
Calc calculator;
TS_ASSERT_EQUALS(calculator.a, 42);
TS_ASSERT_EQUALS(calculator.add(1,2), 3);
}
}
The problem
The problem being is, when I do cxxtestgen --error-printer -o runner.cpp CalcTestSuite.h && g++ -I$cxxtest -o runner.o runner.cpp && ./runner.o, an error occurs:
runner.cpp: (.text._ZN13...(many letters)): undefined reference to `Calc::add(int,int)`
Undoubtedly, the reason of that is wrong compiling as I compile code outside of Visual Studio 2019 or other IDE.
How I tried to solve the problem:
I see a couple of solutions:
1.) Leave build command as is and add #include "Calc.cpp" to TestSuite file, which will obviously work but would be a bad practice.
2.) Add Calc.cpp to g++ command: g++ -I$cxxtest -o runner.o Calc.cpp runner.cpp && ./runner.o, however, it leads to another problem:
Calc.cpp:3:7: error: redefinition of 'class Calc'
In that case I also tried changing #pragma once to #ifndef CALC_H... block in Calc.h, but the error remained.
I tried searching for real-world cxxtest code examples, but didn't find the site I've seen long ago. I would be glad to recieve any tips on what's the best way to deal with this issue.
And if you know the site where I can search for real-life code snippets I would be glad if you shared it.
There are two problems:
You are violating One Definition Rule! You can't redefine Calc like this:
#include "Calc.h"
class Calc {
public:
int add(int a,int b){
return a + b;
};
}
It must be:
#include "Calc.h"
int Calc::add(int a,int b) {
return a + b;
};
const int Calc::a;
Now this problem do not surfaces since you do not build this cpp and you should.
You didn't explain how you are building you code. Simplest way when it is done manually it can look like this:
cxxtestgen --error-printer -o CalcTestSuite.cpp CalcTestSuite.h
g++ -std=c++17 -Wall -Wextra Calc.cpp CalcTestSuite.cpp -o test
Offtopic: this cxxtest test framework is strange and has strange/complex build process of test. It would be better if you learn to use something more useful, Catch2 is great and easy to use (no funny build process) and it is supported by godbolt.
This question may seem similar to other "undefined reference error when accessing static class member" questions. I have explored them and what I understood is I need to define the static class member separately in a source file, so that an object is created for the static class member that holds data.
My problem is that I am following definition rules but still get the undefined reference errors.
problem can be reproduced using this code:
main.cpp
#include <iostream>
#include "src/a.hpp"
int main() {
std::cout << a::x;
return 0;
}
src/a.hpp
class a {
public:
static int x;
};
src/a.cpp
#include "a.hpp"
int a::x = 20;
I compile main.cpp using g++ main.cpp -o main. I have a test directory that has main.cpp and a sub directory src, src contains a.hpp and a.cpp.
The error resolves if i define the static variable within the header file, but other posts suggest it should lead to linker errors.
The problem was in the compile command I used, g++ main.cpp -o main does not compile src/a.cpp. Compile it with g++ main.cpp src/a.cpp -o main and it works fine.
Obviously something goes wrong with my understanding of this topic, but I can't find out where. The thing I want to implement is a custom Exception called CustomException. What I have made does compile and can work, but I do think that I am making use of header files the wrong way. So I have made the following 3 files:
main.cpp
#include "exception.h"
int main() {
try {
throw CustomException();
} catch (CustomException ce) {
ce.doSomething();
}
}
exception.h
#include <exception>
class CustomException : public std::exception {
private:
char* msg;
public:
CustomException() {};
void doSomething() {};
};
exception.cpp
#include "exception.h"
CustomException::CustomException() {
}
void CustomException::doSomething() {
printf("Hello World!");
}
After I run this is the command line:
$ g++ main.cpp -o main.o
$ ./main.o
$
But the behaviour that I was looking for is, that "Hello World!" is printed to the command line. I am more used to JAVA, so maybe that is why I have a rough start with C++. Anyways I hope you can help me, because the tutorials I found differ from each other and don't make sense to me.
Your problem is that you're defining CustomException::doSomething() to do nothing: {}. Leave out the {} method definitions in exception.h. Then compile and link exception.cpp into your binary:
$ g++ -c main.cpp -o main.o
$ g++ -c exception.cpp -o exception.o
$ g++ main.o exception.o -o main
$ ./main
Note that a ".o" suffix is normally used for object files, not for executables.
In addition to what user3553031 said, there is another posslble problem with your code. In C++ you should catch exceptions by reference, not by value. Otherwise it can cause problems. See this: C++ catch blocks - catch exception by value or reference?
I am migrating from Java to C++. It seems that C++ makes classes declaration in separate files, difficult. So I need your help,
in my main.cpp:
#include "Sphere.h"
using namespace std;
.....
...
..
int main( void ) {
Sphere *earth = new Sphere(sphere_start ,sphere_end);
...
..
.
in my Sphere.h
class Sphere
{
public:
Sphere(int,int);
}
and in my Sphere.cpp
#include "Sphere.h"
using namespace std;
int sphere_start, sphere_end;
Sphere::Sphere (int a, int b)
{
sphere_start = a;
sphere_end = b;
}
void Sphere::render(int i)
{
....
..
.
}
This is the very basic code that I think causes the following error:
main.cpp:14:20: fatal error: Sphere.h: No such file or directory
compilation terminated.
why?
You need to add to your compile command a path to where the header files can be found.
If your header is in the headers directory add -Iheaders:
g++ -o main.o -c -Iheaders main.cpp
g++ -o sphere.o -c -Iheaders sphere.cpp
g++ -o app main.o sphere.o -L.
Or whatever your files are ...
Sphere.h must either be in the same directory as each file that includes it, or the compiler must be directed to search the directory in which Sphere.h is located.
You should post your command line, but my guess is that you should tell the path to the header files to the compiler. If you're using linux try this:
g++ main.cpp shpere.cpp -I<path_to_Sphere.h> -o main
Two potential errors:
Is Sphere.h in the same directory as main.cpp?
Is Sphere.h named Sphere.h and not sphere.h?
I have problem and no idea how to resolve it. I believe this is stupid trivial:
I have 3 files:
Util.hpp
class Util
{
public:
class BitParser
{
public:
static bool getBitAt(int buf, int idx);
};
};
Util.cpp
#include "Util.hpp"
bool Util::BitParser::getBitAt(int buf, int idx)
{
return true;
}
application.cpp
#include "Util.hpp"
int main(int argc, char* argv[])
{
Util::BitParser::getBitAt(1,1);
}
Of couse, files listed above are in the same directory. And now when I try to link and compile I recieve linker error:
$ g++ -o app application.cpp
application.cpp:(.text+0x19): undefined reference to `Util::BitParser::getBitAt(int, int)'
collect2: ld returned 1 exit status
What is screwed up?
You told g++ to compile your 'main' program, but didn't tell it about the Util module. Add Util.cpp to the command line and all should work well.
The compiler has brewn an "application.o" file that refers to the Util::bitparser functions.
The linker should 'link' these referrals to the "util.o" file, containing the actual code for these functions. But it has no .o file containing a function satisfying the link. That's what it calls "undefined reference": "application.o" refers to a function the linker doesn't find.
You need to compile (and link) all the .cpp files. So in your case, the command would be
$ g++ -o app application.cpp Util.cpp
Better still, write a Makefile to do this for you.
You have to include both application.cpp and Util.cpp in the build.