simple C++ code linker error [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.
Im trying to run a very simple snippet of code. I've been getting a linker error. My code looks like this:
main.cpp -->
#include <iostream>
#include "Complex.h"
using namespace std;
int main()
{
Complex c1(1.0, 5.0); // this should create Complex object 1.0 + i5.0
return 0;
}
Complex.h -->
#include <iostream>
class Complex {
private:
double real;
double imaginary;
public:
Complex(double, double);
void setReal(double);
void setImaginary(double);
};
Complex.cpp -->
#include "Complex.h"
#include <cmath>
Complex::Complex(double x, double y) {
setReal(x);
setImaginary(y);
}
void Complex::setReal(double x) {
real = x;
}
void Complex::setImaginary(double x) {
imaginary = x;
}
The error I've been getting looks like this:
I have been trying to run my main for a while but I keep getting the linker error. I have no clue what's causing it. I would appreciate any suggestions.

Just do
g++ main-3.cpp complex.cpp
mind the filename main-3, this is inconsistent in your question.
You have to feed all cpp files you are using into the g++ commandline to tell g++ where the code for the functions defined in the header lies. Read up on .o files, static linking and understand what that means.
Here is a little guide I follow to understand file inclusion and other factors:
c++ compilation is moronically simple:
read .cpp file
replace every #include statement with the text of the specified file (just dump it in)
If the resulting text still has #include directives (now from the header files), goto step 2.
Compile the hughe messy blob into a ´.o´ object file, replace calls to functions with symbols and add to that file a table of known symbols and where they are defined.
if there are more .cpp files specified, start a new empty text blob. Goto step 1.
call the linker ´ld´ to link all object files together, replace symbols with the actual addresses.
Strictly speaking, above is a little bit of a lie nowadays and a lot is left out and no optimizations mentioned. But it is still a useful guide to the compiler's behaviour.
To use it to interpret your error:
Complex.h got dumped into your blob, via the #include in main.cpp , but Complex.cpp did not. g++ generated an internal temporary .o file for you that contained something along the lines of
PUT 1.0 on Stack
PUT 5.0 on Stack
JUMP Complex::Complex
... and ran the linker ´ld´ with that .o file.
ld Could not find the address of the symbol Complex::Complex,
it needs a memory address to jump to.
If you compile Complex.cpp as well, the resulting Complex.o will have a symbol table with, for example, this entry:
Complex::Complex = 0xaaff
The linker, given Complex.o can now replace the symbol in main.o with an address.
PUT 1.0 on Stack
PUT 5.0 on Stack
JUMP 0xaaff

Related

FPC: file not recognized: file format not recognized

I have something that need to link some C++ codes to main Pascal program. I followed this tutorial, now I have:
download.h
#include <iostream>
#include <curl/curl.h>
using namespace std;
// function goes here
int downloadsrc(char* pkg_name){
// do stuff
}
download.pas:
unit download;
{$link download.obj} // fpc may overwrite download.o
Interface
uses ctypes;
function downloadsrc(pkg_name:string):integer;
Implementation
// I leave this empty
end.
My main program:
program myprog;
uses
warn, download, test;
var i:integer;
begin
if ParamCount = 0 then help()
else for i:= 1 to ParamCount do
begin
if ParamStr(i) = 'download' then downloadsrc(ParamStr(i+1))
else if ParamStr(i) = 'test' then test();
end;
end.
I tried g++ to compile .h file, change the output.. but when build the program FPC says that:
download.obj: file not recognized: file format not recognized
Compiling download.pas manually still works.
Am I do something wrong here? Am I need to do some other things, like add a compile flag or modify the code?
FPC, like GCC, uses COFF objects. Make sure your .obj is COFF not OMF.
If you fix that, you probably must also link some C++ runtime library, and declare downloadsrc in a C callable way, and alter the FPC declaration to match (cdecl)

Duplicate Symbols in object files:

I am trying to compile two .cpp files, (foo.cpp and bar.cpp) and build a shared object (project.so). But the compilation fails and (a part of) the error I am getting is:
....
duplicate symbol _n in:
foo.o
bar.o
ld: 5 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1(use -v to see
invocation)
make: *** [project.so] Error 1
ERROR: compilation failed for package ‘project’
My .cpp files have few common and uncommon header files, a few commonly and uncommonly named functions, and a set of commonly named variables:
foo.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <ctime>
#include <cmath>
size_t m1;
double k1=2.0;
std::vector<double> x,y;
std::vector<double> z;
size_t n,p;
void inputfoo(){...}
void output(){...}
bar.cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <ctime>
#include <cmath>
#include "Eigen/Dense"
#include "Eigen/Cholesky"
size_t m2;
double k2=2.0;
std::vector<double> x,y;
std::vector<double> z;
size_t n,p;
void inputbar(){...}
void output(){...}
My attempt:
I am able to get lesser number of 'duplicate symbols' error if I differ the names of global variables in each .cpp files. That is, if I change the size_t m to size_t m1 in foo.cpp and size_t m2 in bar.cpp, i do not get this part in the error
duplicate symbol _m in:
foo.o
bar.o
So, now I can see that the 5 symbols in the errors are for x,y,z,n,p ( defined globally in each .cpp file)
Same goes if I differ the name of the commonly named functions. Previously, I would also get this part in the error,
duplicate symbol __Z4inputP4init3RNGPi in:
foo.o
bar.o
which directs me to the input(){...} function.
So, I changed the name of one of the commonly named function ( input (){..} ), to inputfoo and inputbar and the respective error went away.
Now, I am sure i will be able to compile these two successfully if i make the names unique in each file. However, I cant change the x,y,z,n,p because they are numerous in these files and I have many more files to work with which have common named functions and variables.
Can anyone please explain it to me what is happening here and how to fix it? I would really like to know what is causing this. I tried reading from previous posts, 'Understanding the origin of a linker duplicate symbol error ' but I don't think it is a header related problem.
Thank you so much.
The example is incomplete, which makes it hard to comment.
But let me make a guess: you have globals in both files and they are visible across both. That is a design error. You can either
make them local to each file if their state is not shared, use static for that
make them shared by declaring one file only and using extern in the other.
But the error you quote is different and we don't know anything about your input::init()...
Also, I also see nothing related to Rcpp here, so wht add the tag for it?

Instantiating & using c++ class using header & implementation files [duplicate]

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.
I'm basically trying to instantiate an object from a class in c++ and use one of the member functions. This feels like a pretty standard problem, but all of the solutions I find online are either simple bracket issues, or scope resolution stuff that seems really obvious, or massively complex examples that shroud what's actually going on in over-complexity. I really appreciate anyone that Might be able to help me understand what I'm doing wrong with these files.
The errors I get are
undefined reference to Test::Test()'
undefined reference to Test::msg()'
I have three files, a main, a Test.hpp, and Test.cpp.
main.cpp
#include "Test.hpp"
#include <iostream>
using namespace std;
int main(){
Test var;
var.msg();
return 0;
}
Test.hpp
#ifndef TEST_HPP
#define TEST_HPP
class Test{
public:
Test();
void msg();
};
#endif
Test.cpp
#include "Test.hpp"
#include <iostream>
using namespace std;
Test::Test(){
cout << "instantiated\n\n";
}
void Test::msg(){
cout << "Hello\n\n";
}
Considering you use codeblocks as your IDE just go to: project settings -> project build options -> search directories -> add and locate where your .cpp and .h files are. Then it will ask you if you want to keep this as relative path. Say no.
If you using some other ide its almost the same proccess, just comment me and i will provide you the steps.
Btw there is no need to include iostream in main since you have already included it in test.

Trying to use functions in a header/cpp file

I have two files:
hello.h and hello.cpp
hello.h
#ifndef __HELLO_H__
#define __HELLO_H__
using namespace std;
void PrintMessage();
#endif
hello.cpp
#include <iostream>
#include "hello.h"
using namespace std;
void PrintMessage()
{
cout << "I want to be displayed!";
}
Now, I want to use PrintMessage() in a new .cpp file, but I keep getting an error message. This is what I'm doing:
printingmessage.cpp
#include <iostream>
#include "hello.h"
using namespace std;
int main()
{
PrintMessage();
return 0;
}
Am I just doing something blatantly wrong? I do have all of them in the same folder; I assume it has something to do with Dev-C++ (what I'm using to write/compile/run), but I can't figure it out. Anyone have any ideas?
I created a folder on my desktop, put all three files inside, and I tried to compile my printingmessage.cpp file exactly as it is. This is the error I'm getting:
[Linker error] Undefined reference to 'PrintMessage()'
i don't know dev C++ , but i would strongly advise if you do any serious coding to learn/move to the terminal and use make files, or a newer IDE such as visual studios.
heres a short script you can run save it as bash.sh
something like this
g++ hello.cpp -O2 -g -c
g++ hello.o printmessage.cpp -Wall -O2 -o print
then run it with ./print
I assume it has something to do with Dev-C++ (what I'm using to
write/compile/run), but I can't figure it out.
I guess so, too. Behind the scenes, the following things have to happen:
Both files get compiled. This creates a *.obj file for every *.cpp file, and uses the header.
The object files are linked against one another and possibly against required libraries.
Your problem lies in the “one another” part of the second step: the code compiles all right, but linking fails. The header file is irrelevant at that point. More precisely, the linker invocation for printingmessage.obj contains a reference to a function which isn't defined in that object file or any of the default libraries. Most likely the problem is due to the *.cpp files not being part of the same project. You need to create a multi-source-file project where you can link multiple object files. How you do that with Dev-C++ is probably somewhere in their manuals.

Yet another linker issue

I'm having a linking issue with a basic C++ program. No, I'm not including .cpp files!
This is what's happening.
main.cpp:
#include "header.h"
#include <iostream>
int main() {
std::cout << "Hello!";
}
header.h:
#ifndef _HEADER_H
#define _HEADER_H
class Something {
public:
printContents();
};
#endif
something.cpp:
#include "header.h"
#include <iostream>
Something::printContents() {
cout << "This class's Contents!!";
}
What's happening is that I get a compiler error going: multiple definitions of some standard C function, such as strtod:
g++ -o ... main.o
build/....main.o: In function
`strtod':
../MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/stdlib.h:318:
multiple definition of `strtod'
build/..something.o:...something.cpp:(.text+0x0):
first defined here collect2: ld
returned 1 exit status
If I get rid of #include <iostream> in one of the two occasions and get rid of the couts, it will compile. What's going on? I'm using g++ and NetBeans to compile.
I tried in the command line:
g++ *.h *.cpp -o program
and the same thing happened.
Please note that _HEADER_H is an illegal name in C++ user code - names beginning with the underscore and an uppercase letter are reserved for the C++ implementation. This does not normally cause noticeable problems, but when you use what may be a common name in the implementation like HEADER in this context, it well might.
Modify,
Something::printContents()
{
std::cout << "This class's Contents!!";
}
NOTE: Specify the return datatype.
One of your problems is right here:
I tried in the command line: g++ *.h
*.cpp -o program
Don't pass your header files... Try something like this:
g++ *.cpp -o program
I could not reproduce your exact problem. I get this to compile and link nicely with the following few notes:
Add a void return type to the printContents-function (So it says void printContents(); in the header and void Something::printContents() { in the implementation-file)
Use std::cout rather than just cout. cout is not defined in the scope it is used
Make sure header.h ends with a blank line
Use HEADER_H rather than _HEADER_H (like Neil Butterworth says)
I use the command line g++ main.cpp something.cpp to compile.
I see a couple of problems. You shuold define the returning value of the function
printContents()
and you must write
std::cout
if you don't write
using namespace std;
The problem was in a multi-installation of MinGW. I had one already installed, and when I got Qt on my computer, it had installed it's own MinGW. Bummer, I ported the code to my university's servers and it ran OK.
Bummer!!
Thanks everybody for the help, I will definitely follow your guidelines in the future.
Header names - no underscores
Correct return type
Real code in the forums!
Leo Bruzzaniti