C++: Linking files with GCC compiler - c++

I have three files : myh.h; my.cpp; use.cpp. Here are the contents of the files:
myh.h
extern int foo;
void print_foo();
void print(int);
my.cpp
#include "myh.h"
#include <iostream>
void print_foo()
{
std::cout<<foo<<std::endl;
}
void print(int i)
{
std::cout<<i<<std::endl;
}
use.cpp
#include "myh.h"
int main()
{
foo=7;
print_foo();
print(99);
return 0;
}
GCC spews out the following error:
my.o:my.cpp:(.text+0x7): undefined reference to `foo'
use.o:use.cpp:(.text+0x10): undefined reference to `foo'
collect2: ld returned 1 exit status
I compile the files using the -c command and it doesn't give errors. I link using the following command:
g++ -o final my.o use.o
What is the problem here, I read other topics with similar problems, and the case here is just strange .....
For the curious this is an exercise drill from Stroustrup's book Programming principles of using C++
Edit: I did as dasblinkenlight said, and in use.cpp I added an int in front of foo (so now foo is defined), but I still get this error:
my.o:my.cpp:(.text+0x7): undefined reference to `foo'
collect2: ld returned 1 exit status
Which tells me that it is not defined in my.cpp also? If I have to define it everywhere what is the point of including it in the header file, or how should this be approached more appropriately?

You get a linker error because you declared foo, but you never defined it.
extern int foo is only a declaration; it does not cause allocation of memory for the foo variable, only promises that you will do it at some other place. To fix it, you need to add this line to one of the cpp files, like this:
#include "myh.h"
int foo;
int main()
{
foo=7;
print_foo();
print(99);
return 0;
}

The problem is that foo is declared but not defined. You need to define foo in exactly one of the translation units, e.g.:
int foo = 0;

Related

"Undefined Refrence to Foo" while compiling with G++

I have three files:
my.cpp
#include "my.h"
#include <iostream>
void print_foo() {
cout << foo << '\n';
}
void print(int i) {
cout << i << '\n';
}
my.h
extern int foo;
void print_foo();
void print(int);
use.cpp
#include "my.h"
int main(int argc, char *argv[]) {
foo = 7;
print_foo();
print(99);
return 0;
}
Now when I run g++ my.cpp use.cpp I get the error
/usr/bin/ld: /tmp/ccUKJUlZ.o: in function `print_foo()':
my.cpp:(.text+0x6): undefined reference to `foo'
/usr/bin/ld: /tmp/ccN0mIhY.o: in function `main':
use.cpp:(.text+0x11): undefined reference to `foo'
collect2: error: ld returned 1 exit status
Additionally, if I run g++ -c my.cpp everything goes alright, but, if I then run g++ my.o use.cpp I get the same error.
You never actually define a variable foo - in both use.cpp and my.cpp, you use foo, and in my.h you declare it as an extern.
See the beginning of this response for more information on declaring vs. defining. You may think that your problem would be solved if you added a type in front of your foo = 7 line in use.cpp; however, what you also need to do is make foo a global variable instead of a local one (which it is when you declare it simply within main), as extern will only "find" variables that have global scope. You can make a variable global by declaring it outside of any function (side note - you should only use global variables when you absolutely have to).
Therefore, you could solve your problem by changing your use.cpp to the following:
#include "my.h"
int foo = 7;
int main(int argc, char *argv[]) {
print_foo();
print(99);
return 0;
}

How to wrap functions with the `--wrap` option correctly?

The man page of gcc 6.3 says:
--wrap=symbol
Use a wrapper function for symbol. Any undefined reference to
symbol will be resolved to "__wrap_symbol". Any undefined
reference to "__real_symbol" will be resolved to symbol.
...
If you link other code with this file using --wrap malloc, then all
calls to "malloc" will call the function "__wrap_malloc" instead.
The call to "__real_malloc" in "__wrap_malloc" will call the real
"malloc" function.
So I created a simple example:
#include <stdio.h>
int foo() {
printf("foo\n");
return 0;
}
int __wrap_foo() {
printf("wrap foo\n");
return 0;
}
int main () {
printf("foo:");foo();
printf("wrapfoo:");__wrap_foo();
printf("realfoo:");__real_foo();
return 0;
}
And compiled it with:
gcc main.c -Wl,--wrap=foo -o main
This gave me a warning:
main.c:18:21: warning: implicit declaration of function ‘__real_foo’ [-Wimplicit-function-declaration]
printf("realfoo:");__real_foo();
^~~~~~~~~~
Well going on. Now I would suggest an output like this:
foo:wrap foo
wrapfoo:wrap foo
realfoo:foo
Instead I get this:
foo:foo
wrapfoo:wrap foo
realfoo:foo
I hope the thing is clear. I am confused about the warning. Normally the __real function should be linked by the linker to foo(). Furthermore a call to foo() should be linked to __wrap_foo. But the output showes, that foo() is being executed instead.
How to use --wrap correctly?
As StoryTeller told me, I ignored the "undefined reference" requirement which I already posted above:
... Any undefined reference to symbol will be resolved to "__wrap_symbol". Any undefined reference to "__real_symbol" will be resolved to symbol.
To use the --wrap option I rearranged my code example like this:
main.c:
#include <stdio.h>
extern int foo();
extern int __real_foo();
int __wrap_foo() {
printf("wrap foo\n");
return 0;
}
int main () {
printf("foo:");foo();
printf("wrapfoo:");__wrap_foo();
printf("realfoo:");__real_foo();
return 0;
}
foo.c:
#include <stdio.h>
int foo() {
printf("foo\n");
return 0;
}
Then compile:
gcc main.c foo.c -Wl,--wrap=foo -o main
And the the amazing output after running ./main:
foo:wrap foo
wrapfoo:wrap foo
realfoo:foo
The trick is (correct me if I am wrong) that the reference of foo() and __real_foo() is not defined at compile time. I. E. they have **undefined references" which is the requierement for the linker to link foo() to __wrap_foo() and __real_foo() to foo().

Nested class, undefined reference, static method

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.

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)

Calling member functions of a class object which is present in header file included

I am new to the forum i wanted to call a member function of an included header file..Here is code i have written
#include<stdio.h>
#include "Abc.h"
CAbc *a;//CAbc is a class present in Abc.h
int main(int argc,char **argv)
{
int i=10;
float j=15.5;
bool x;
x=a->method(i,j);//method is a member function of CAbc
if(x)
{
printf("Working Correctly");
}
else
{
printf("Not Working");
}
}
If i compile this using
g++ -I/path/to/include code.cpp
I get the Error
/tmp/cc5JgLfF.o: In function `main':
code.cpp:(.text+0x3d): undefined reference to `CAbc::method(int,float)'
collect2: ld returned 1 exit status
I also tried giving
x=a::method(i,j);
for which i get a is not a class or namespace
Please can anyone tell me am i doing it correctly or not?
It looks as though you are forgetting to include the implementation source/object.
Try this:
g++ -I/path/to/include Abc.cpp code.cpp
as long as your implementation class for Abc.h corresponds to Abc.cpp.
Regards,
Dennis M.
Does your make file or whatever link CABC.obj to the whole exe? If so, then you have forgotten to write the implementation (body, definition) of method...
As others have said, make sure there's an implementation of CAbc.method being linked. Additionally, you need to allocate and deallocate the memory for pointer 'a'; at the moment it's uninitialized.
a = new CAbc();
...
del a