Nested class, undefined reference, static method - c++

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.

Related

undefined reference error for static class member when it is defined in .cpp file

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.

Problems linking static library to c++ project with MinGW

Edit: ***Sorry I realize there must have been some misunderstanding when posting this question, I want to specify that I DO realize this question was asked a few times, none of the answers work for me however***
I've been trying to link a simple static library test to one of my c++ projects, but I can't seem to get it quite right. I know that this is a very widespread topic and that a lot of people have already asked a similar question, but even after reading some of the answers, I still cannot, for the love of god, figure out what I am doing wrong.
My code is very simple, first I have a .cpp source file titled "Math.cpp" that looks like this:
#include "Math.h"
int max(int a, int b) {
return a > b ? a : b;
}
int min(int a, int b) {
return a < b ? a : b;
}
int floor(double a) {
return (int) a;
}
int ceil(double a) {
return (int) a + 1;
}
..And to go with that I made a header file called "Math.h" that looks like this:
#pragma once
int max(int, int);
int min(int, int);
int floor(double);
int ceil(double);
I then compile "Math.cpp" with the following command on cmd:
g++ -c Math.cpp -o Math.o
...and then compile it into a static library like so:
ar rcs libMath.a Math.o
After all of this I make a new c++ soure file titled "Main.cpp" that looks like this:
#include <iostream>
#include "Math.h"
int main() {
std::cout << max(9, 8) << std::endl;
return 0;
}
("Math.h" is in the same directory as "Main.cpp")
So finally in order to link "Main.cpp" with my static library ("libMath.a"), I use the following command in cmd:
g++ -o Main.exe Main.cpp -L. -lMath
however, at this point, it throws the following error:
C:\Users\zalmar\AppData\Local\Temp\ccmOnvyg.o:Main.cpp:(.text+0x18): undefined reference to `max(int, int)'
collect2.exe: error: ld returned 1 exit status
... I cannot figure out why it can't find the reference to the specific function. Some people appeared to have the same problem (here for example). Their solution was to declare the Main.cpp source file before declaring the library path. However, that was not the case for me, even though I made sure I was linking the library after the Main.cpp it still came up with the same error. I would greatly appreciate it if someone could point out anything I might be doing wrong because clearly I must be doing something wrong. Otherwise it might be a problem with my MinGW compiler, maybe?
I also want to re-mention that this is just a test library and I am fully aware that it might be a bit overkill to compile an entire static library from such a simple program. I am simply trying to figure out how to link libraries to my c++ projects...

Get undefined reference when compiling C++ client for ZooKeeper

I try to compile my very first program in C++ in which I try to connect to ZooKeeper and do some other stuff. In my code I have these lines:
//test.cpp
#include "zookeeper.h"
... all other header files from zookeeper/include
void main_watcher (zhandle_t *zkh,
int type,
int state,
const char *path,
void* context)
{
if(type == ZOO_SESSION_EVENT){
if(state == ZOO_CONNECTED_STATE){
...
}
...
}
}
int main(){
return 0;
}
But when I compile this test.cpp file (indeed, I provide link to the zookeeper/.../build/usr/lib and path to all included files), I get a list of these error messages:
undefined reference to ZOO_SESSION_EVENT
undefined reference to ZOO_CONNECTED_STATE
...
What am I doing wrong?
You're forgetting to link agains zookeeper, most probably. Typically, you'd have to do something like
g++ -lzookeper -o yourprogram yourprogram.c
maybe it's
-lzookeeper-mt
maybe not. Usually, it's job of a build system to figure these things out for you.

Boost.Python - Exposing a class

I have the following class called "Wav" which is stored in another directory, with the files "Wav.h" and "Wav.cpp" and looks like the following:
enum ReadType {
NATIVE = 0,
DOUBLE,
};
namespace AudioLib {
class Wav : public Signal {
public:
Wav();
Wav(const int M, const int N);
///... ->
};
};
The .cpp file contains the implementation of this class, everything compiles well.
I'm trying to implement a Python wrapper using boost.python and have the following file:
#include <boost/python.hpp>
#include "../src/Wav/Wav.h"
using namespace boost::python;
BOOST_PYTHON_MODULE(Wav)
{
class_<AudioLib::Wav>("Wav",
init<const int, const int>());
}
In my Makefile, I am compiling the Wav.cpp:
# Compile the .wav Python and Cpp file
$(WAV_TARGET).so: $(WAV_TARGET).o
g++ -shared -Wl,--export-dynamic $(WAV_TARGET).o -L$(BOOST_LIB) -lboost_python -
lboost_python -L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) -o
$(WAV_TARGET).so
$(WAV_TARGET).o: $(WAV_TARGET).cpp
g++ $(CFLAGS) ../src/Wav/Wav.cpp -I$(PYTHON_INCLUDE) -I$(BOOST_INC) -fPIC -c
$(WAV_TARGET).cpp
And whenever I try to import into Python I get the following:
ImportError: Wav.so: undefined symbol: _ZN8AudioLib3WavC1Eii
Where am I going wrong?
It looks like you have failed to define the second constructor:
Wav(const int M, const int N);
I can replicate the error message by making a working (but simplified) copy of your example with in-line definitions and just removing the definition of that constructor. So my advice would be to check carefully for the definition in Wav.cpp and try creating an in-line definition to experiment.
If the definition does exist, maybe the linker flags are not right.

C++: Linking files with GCC compiler

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;