Undefined reference to static queue - c++

I'm new with C++ pthreads. What I'm trying to do is use one thread to catch UDP packets and put it into a queue, and another one to process them and send them after. My question is, how can I push/pop elements into/from a container in a separate thread?
Here's an example:
#include <queue>
#include <iostream>
#include <pthread.h>
#include <signal.h>
class A{
public:
A(){
pthread_create(&thread, NULL, &A::pushQueue, NULL);
pthread_join(thread, NULL);
}
virtual ~A(){
pthread_kill(thread, 0);
}
private:
static void* pushQueue(void* context){
for(int i = 0; i < 10; i++){
bufferInbound.push(i);
std::cout << i << " pushed!" << std::endl;
}
}
static std::queue<int> bufferInbound;
pthread_t thread;
};
int main(){
A* a = new A();
return 0;
}
When I compile, it gives me the following result:
U53R#Foo:~/$ make
g++ -g -lpthread main.cpp -c
g++ -g -lpthread main.o -o this
main.o: In function `A::pushQueue(void*)':
/home/U53R/main.cpp:20: undefined reference to `A::bufferInbound'
collect2: ld returned 1 exit status
make: *** [make] Error 1
Thanks for helping.

you need to initialize the static member, add std::queue<int> A::bufferInbound; after the class or move it inside your function.

Related

Error message "undefined reference to 'List::a'"

I am getting the error shown below while linking the code. How can I fix this problem?
It seems the static variable is not getting initialized.
#include <iostream>
#include <cstdlib>
using namespace std;
struct name{
char c;
};
class List {
static name *a;
public:
static void modify()
{
a = new name();
cout<<"yes";
}
};
name List::*a = NULL;
int main()
{
List::modify();
}
g++ O3 -Wall -c -fmessage-length=0 -o sample.o "..\\sample.cpp"
g++ -o sample.exe sample.o
sample.o:sample.cpp:(.text.startup+0x35): undefined reference to `List::a'
collect2.exe: error: ld returned 1 exit status
name List::*a = NULL; doesn't do what you expected. It defines a global variable named a, which is a pointer to non-static member of List of type name.
The definition of List::a should be
name* List::a = NULL;

undefined reference to pthread create even with lpthread [duplicate]

This question already has answers here:
Difference between -pthread and -lpthread while compiling
(3 answers)
Closed 4 years ago.
I want to make use of pthread ad hence use the -lpthread flag to compile, but here's what I get:
$ g++ -lpthread pseudo_code.cpp
/tmp/cc3mPrvt.o: In function `MyThreadClass::StartInternalThread()':
pseudo_code.cpp:(.text._ZN13MyThreadClass19StartInternalThreadEv[_ZN13MyThreadClass19StartInternalThreadEv]+0x26): undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
The code I try to compile is below:
#include <pthread.h>
#include <iostream>
#include <vector>
#define OK 0
#define ERROR -1
//-- ThreadClass
class MyThreadClass
{
public:
MyThreadClass() {/* empty */}
virtual ~MyThreadClass() {/* empty */}
/** Returns true if the thread was successfully started, false if there was an error starting the thread */
bool StartInternalThread()
{
return (pthread_create(&_thread, NULL, InternalThreadEntryFunc, this) == 0);
}
/** Will not return until the internal thread has exited. */
void WaitForInternalThreadToExit()
{
(void) pthread_join(_thread, NULL);
}
protected:
/** Implement this method in your subclass with the code you want your thread to run. */
virtual void InternalThreadEntry() = 0;
private:
static void * InternalThreadEntryFunc(void * This) {
((MyThreadClass *)This)->InternalThreadEntry(); return NULL;
}
pthread_t _thread;
};
//-- /ThreadClass
//--- DUMMY DECLARATIONS BELOW TO MAKE IT COMPILE ---//
#define LOG_NS_ERROR std::cout
class test{
public:
int get_child(std::string x){return OK;};
};
test *_global;
typedef struct test_struct{} _db_transact;
class db_transact{
public:
db_transact(int,int&,int&){};
};
int _ns;
int _log_id;
//--- DUMMY DECLARATIONS ABOVE TO MAKE IT COMPILE ---//
class db_c_hndlr : public MyThreadClass{
public:
db_c_hndlr(void);
~db_c_hndlr(void);
db_transact *db_conn_get(void);
void InternalThreadEntry(void *func);
private:
int _stop;
std::vector<db_transact*> _db_pool;
};
//---------------------------------------------------------
db_c_hndlr::db_c_hndlr(void) {
}
//---------------------------------------------------------
void db_c_hndlr::InternatThreadEntry(void *func) {
while(!stop){
std::cout << "going!" << std::endl;
sleep(1);
}
}
//---------------------------------------------------------
db_c_hndlr::~db_c_hndlr() {
int i = 0;
std::vector<db_transact*>::iterator it;
for (i=0, it = _db_pool.begin();it!=_db_pool.end();it++, i++) {
if (_db_pool[i])
if (_db_pool[i]!=NULL)
delete _db_pool[i];
}
}
//---------------------------------------------------------
db_transact *db_c_hndlr::db_conn_get(void) {
db_transact *tmp;
tmp = new db_transact(_global->get_child("db_config"), _ns, _log_id);
_db_pool.push_back(tmp);
return tmp;
}
//---------------------------------------------------------
int main(void)
{
db_transact *conn=NULL;
db_c_hndlr db;
//db = new db_c_hndlr();
conn= db.db_conn_get();
return OK;
}
Probably you need to do this:
extern "C" {
#include <pthread.h>
}
That tells the compiler that this header is for a C library, and that it should not use C++ name mangling.
You also need to use -pthread instead of -lpthread, because the pthread library is special and GCC wants to explicitly know you are trying to use threads, not simply link against libpthread.
Please try to compile with the command.
g++ pseudo_code.cpp -lpthread
It makes a difference where in the command you write this option; the
linker searches and processes libraries and object files in the order
they are specified. Thus, foo.o -lz bar.o searches library z after
file foo.o but before bar.o. If bar.o refers to functions in z, those
functions may not be loaded.
It worked for me. It seems, needs to specify the library after the source file so that symbols are searched in the library.

G++ - Undefined Reference to member function that is defined

I am currently working on a virtual run time environment program that is at a very early stage, i am prevented from continuing my work due to a linker error when using my makefile, provided below. The error i am receiving is:
g++ controller.o processor.o test.o -o final
controller.o: In function `Controller::run()':
controller.cpp:(.text+0x1e0): undefined reference to
Processor::codeParams(char)'
controller.o: In function `Controller::fetch()':
controller.cpp:(.text+0x290): undefined reference to `Controller::pc'
controller.cpp:(.text+0x299): undefined reference to `Controller::pc'
collect2: error: ld returned 1 exit status
makefile:16: recipe for target 'final' failed
make: *** [final] Error 1
I am unsure as to why i get this error as i thought i had defined these things in the source file corresponding to the header. All files will be given below so that the program can be compiled.
test.cpp:
#include <iostream>
#include <vector>
#include "includes/controller.h"
using namespace std;
int main()
{
vector<char> prog = {0x0};
Controller contr(prog);
cout << "Error Code: " << contr.run() << endl;
return 0;
}
controller.cpp:
/*
Author(s): James Dolan
File: controller.cpp
Build: 0.0.0
Header: includes/controller.h
DoLR: 21:39 11/1/2017
Todo: n/a
*/
#include "includes/controller.h"
Controller::Controller(vector<char> prog)
{
printf("Program:"); //Display program
for(auto i : program)
{
printf("%02X", i);
}
printf("\n");
Controller::program = program;
}
Controller::~Controller ()
{
}
int Controller::run()
{
bool runFlag = true;
int errorCode = 0;
char curCode;
vector<char> curInstr;
int paramRef;
while(runFlag)
{
curCode = fetch();
printf("curCode:%02X\n", curCode);
curInstr.push_back(curCode);
paramRef = proc.codeParams(curCode);
if (paramRef == 0xffff){runFlag = false; continue;} //Check if shutdown signal was returned, if so shutdown
printf("opcode good\n");
for(int i; i<paramRef; i++){curInstr.push_back(fetch());}
}
return errorCode;
}
char Controller::fetch()
{
return program[pc++]; //Return next instruction then increment the program counter
}
controller.h:
/*
Author(s): James Dolan
File: controller.h
Source: ../controller.cpp
DoLR: 21:39 11/1/2017
Todo: n/a
*/
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <iostream>
#include <vector>
#include <cstdlib>
#include "processor.h"
using namespace std;
class Controller{
public:
Controller(vector<char> prog);
~Controller();
int run();
protected:
private:
vector<char> program;
static int pc;
char fetch();
Processor proc();
};
#endif
processor.cpp:
#include "includes/processor.h"
Processor::Processor()
{
}
Processor::~Processor()
{
}
int codeParams(char code)
{
switch(code)
{
case 0x0: //Halt
return 0;
default:
printf("[ERROR!] Invalid opcode [%02X]", code);
return 0xffff; //Return shutdown signal
}
}
processor.h:
#ifndef PROCESSOR_H
#define PROCESSOR_H
#include <iostream>
#include <cstdlib>
class Processor{
public:
Processor();
~Processor();
int codeParams(char code);
protected:
private:
};
#endif
All if any help is appreciated massively as it will help me to continue with my passion of developing a fully fledged open-source virtual runtime enviroment like the java vm, thank you for your time.
In Controller.cpp you need a int Controller::pc; or int Controller::pc = 0;
In the header file you declared a static int named pc that exists somewhere. It needs to actually exist in a translation unit somewhere (in this case Controller.cpp) so that when the linker tries to find it... it exists.
In Processor.cpp your signature should look like int Processor::codeParams(char code) to let the compiler know that is Processor's codeParams and not a random function named codeParams that happens to also take a character.
For the member function Processor::codeParams you should define it as:
int Processor::codeParams(char code)
// ~~~~~~~~~~~
{
...
}
Otherwise it's just a normal (non–member) function.
For the static member Controller::pc you should define it outside of the class definition, in controller.cpp.
// Controller.h
class Controller {
...
private:
static int pc;
};
// controller.cpp
int Controller::pc;

Could not compile c++ program with threads support on AIX with GCC compiler 4.7.3

I have problem when compiling code below on aix machine with gcc compiler (version 4.7.3):
SomeThread.h
#ifndef SomeThread_H
#define SomeThread_H
class SomeThread {
public:
SomeThread(void);
virtual ~SomeThread(void);
void runThread();
}; // SomeThread
#endif // _SomeThread_H_
SomeThread.cpp
#include "SomeThread.h"
#include <thread>
#include <iostream>
using namespace std;
namespace {
void foo_thread_function() {
for (int i = 0; i < 10; ++i) {
cout << "Some threaded text" << endl;
}
}
}
SomeThread::SomeThread() {
} // SomeThread
SomeThread::~SomeThread() {
} // ~SomeThread
void SomeThread::runThread() {
thread foo_thread_01(foo_thread_function);
thread foo_thread_02(foo_thread_function);
thread foo_thread_03(foo_thread_function);
foo_thread_01.join();
foo_thread_02.join();
foo_thread_03.join();
}
The error which I get is following:
SomeThread.cpp: In member function 'void SomeThread::runThread()':
SomeThread.cpp:58:4: error: reference to 'thread' is ambiguous
In file included from /usr/include/sys/ptrace.h:28:0,
from /usr/include/sys/proc.h:42,
from /usr/include/sys/pri.h:43,
from /usr/include/sys/sched.h:38,
from /usr/include/sched.h:51,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include-fixed/pthread.h:76,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/powerpc-ibm-aix7.1.0.0/pthread/ppc64/bits/gthr-posix.h:41,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/powerpc-ibm-aix7.1.0.0/pthread/ppc64/bits/gthr-default.h:30,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/powerpc-ibm-aix7.1.0.0/pthread/ppc64/bits/gthr.h:150,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/ext/atomicity.h:34,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/memory:75,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/thread:40,
from SomeThread.cpp:5:
/usr/include/sys/thread.h:105:8: error: candidates are: struct thread
In file included from SomeThread.cpp:5:0:
/opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/thread:60:9: error: class std::thread
SomeThread.cpp:58:11: error: expected ';' before 'foo_thread_01'
SomeThread.cpp:59:4: error: reference to 'thread' is ambiguous
In file included from /usr/include/sys/ptrace.h:28:0,
from /usr/include/sys/proc.h:42,
from /usr/include/sys/pri.h:43,
from /usr/include/sys/sched.h:38,
from /usr/include/sched.h:51,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include-fixed/pthread.h:76,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/powerpc-ibm-aix7.1.0.0/pthread/ppc64/bits/gthr-posix.h:41,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/powerpc-ibm-aix7.1.0.0/pthread/ppc64/bits/gthr-default.h:30,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/powerpc-ibm-aix7.1.0.0/pthread/ppc64/bits/gthr.h:150,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/ext/atomicity.h:34,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/memory:75,
from /opt/freeware/lib/gcc/powerpc-ibm-aix7.1.0.0/4.7.3/include/c++/thread:40,
from SomeThread.cpp:5:
I compile the above files with following command line:
g++ -maix64 -DTARGET=target_thread -DGENDATE=04_01_2017 -DTT_LIB_DLLSUFFIX=\".so\" -DOSNAME=\"AIX\" -D_GNU_SOURCE -D_REENTRANT -DAIX -Wno-deprecated -I. -std=gnu++11 -maix64 -pthread -mminimal-toc -fpermissive -Wno-write-strings -Winvalid-offsetof -O3 -c -oSomeThread.o SomeThread.cpp
The problem is, that there are multiple implementations of thread with your compiler options and includes. Maybe it would be just enough to correct the code to this.
SomeThread.cpp
#include "SomeThread.h"
#include <thread>
#include <iostream>
//Stop using namespace std, please
namespace SomeNamespace {
void foo_thread_function() {
for (int i = 0; i < 10; ++i) {
cout << "Some threaded text" << endl;
}
}
}
SomeThread::SomeThread() {
} // SomeThread
SomeThread::~SomeThread() {
} // ~SomeThread
void SomeThread::runThread() {
std::thread foo_thread_01(SomeNamespace::foo_thread_function);
std::thread foo_thread_02(SomeNamespace::foo_thread_function);
std::thread foo_thread_03(SomeNamespace::foo_thread_function);
foo_thread_01.join();
foo_thread_02.join();
foo_thread_03.join();
}
Ambiguous means that there are multiple interpretations of the same word.
Example:
namespace Bla{
struct SomeStruct{
}
}
namespace Blub{
struct SomeStruct{
}
}
int main(){
using namespace Bla;
using namespace Blub;
SomeStruct ImAmbiguous; // Problem now, which struct should the compiler choose now?
Bla::SomeStruct structFromBla; //Now the compiler knows which struct should be choosen
return 0;
}

Calling static C++ method from C gives undefined reference when compiled

Here's a simple set of files that reproduce the problem I'm having:
c.h:
void dummy();
c.cpp:
#include <stdio.h>
extern "C" {
#include "c.h"
}
class Bubu {
public:
static Bubu *getInstance() {
if (_instance == NULL) {
_instance = new Bubu;
}
return _instance;
}
private:
static Bubu *_instance;
};
Bubu *_instance = NULL;
void dummy() {
printf("bubu called\n");
Bubu *ptr = Bubu::getInstance();
}
main.cpp:
extern "C" {
#include "c.h"
}
int main() {
dummy();
return 0;
}
When I compile I get this:
g++ -W -Wall -c c.cpp -o c.o
c.cpp: In function ‘int bubu()’:
c.cpp:24: warning: unused variable ‘ptr’
g++ -W -Wall main.cpp c.o -o main
c.o: In function `Bubu::getInstance()':
c.cpp:(.text._ZN4Bubu11getInstanceEv[Bubu::getInstance()]+0x7): undefined reference to `Bubu::_instance'
c.cpp:(.text._ZN4Bubu11getInstanceEv[Bubu::getInstance()]+0x1d): undefined reference to `Bubu::_instance'
c.cpp:(.text._ZN4Bubu11getInstanceEv[Bubu::getInstance()]+0x24): undefined reference to `Bubu::_instance'
collect2: ld returned 1 exit status
make: *** [main] Error 1
Compilation exited abnormally with code 2 at Tue Dec 15 09:15:21
I've seen the answer to other similar questions but there the problem is either a missing Bubu:: when calling the static method or lack of initialisation of the static member outside the class declaration or missing the extern "C" construct. I'm fairly certain that I'm not making those mistakes ... I'm definitely making other(s).
Can you please explain what's going on?
When you define a static variable inside a class, you have to define it outside the class also. You tried to do this, but
Bubu *_instance = NULL;
will just make a global pointer to Bubu, not instantiate the static one inside the class. You need to use
Bubu *Bubu::_instance = NULL;
to tell the compiler this will be the static variable inside the class.