0

I have seen the standard Undefined Reference to thread from this site but I do not believe it solves my problem. I am not putting header guards on my .cpp files, but still get an undefined reference to a user defined function. Here are my files:

(1) pth_funs.h

// hello from thread <pid>
void* hello(void* ptr);

(2) pth_funs.cpp

#include <stdio.h>

void* hello(void *ptr)
{
  char *message;
  int pid = (long) ptr;
  printf("Hello from thread %i\n", pid);
}

(3) structs.h

#ifndef STRUCTS_H
#define STRUCTS_H
struct grd_str {
  long nx;
  long ny;
  long natoms;
  char** atnames;
  double* xs;
  double* ys;
  double** fs;
  double** xyzs;
};
#endif

(4) fio.h

#ifndef FIO_H
#define FIO_H
#include <iostream>
#include <string.h>
#include "structs.h"

void read_grd(std::string, grd_str);

#endif

(5) fio.cpp

#include <string.h>
#include "structs.h"
#include "fio.h"

void read_grd( std::string fname, grd_str &grd)
{
  grd.nx = 10;
  grd.ny = 10;
}

(6) and finally, xdriver.cpp

#include <iostream> // needed for cout, endl, etc
using namespace std; // needed for cout, endl, etc
#include <pthread.h> // needed for pthreads
#include <string.h> // string handling

#include "pth_funs.h" // pthread function headers
#include "structs.h"
#include "fio.h"

int main(int argc, char** argv)
{
  // thread stuff
  int nthreads = 4;
  pthread_t rank[4];
  int iret[4];

  // file stuff
  string base_dir = "D:\\cygwin64\\home\\Robert\\code\\C\\form_reconstruction\\data\\";
  string fname;

  // topology stuff
  int nx, ny;
  double* xs;
  double* ys;
  double** fs;
  grd_str grd;

  for(long tid = 0; tid < nthreads; tid++)
  { iret[tid] = pthread_create( &rank[tid], NULL, hello, (void*) tid); }

  fname = base_dir;
  fname.append("adf\\adf.6.grd");
  cout << "Filename: " << fname << endl;

  read_grd(fname, grd);
}

I am compiling this using a Makefile which is as follows:

cc=g++
exe=create_grd.exe

flags=-pthread
hds= pth_funs.h fio.h structs.h
objs= pth_funs.o fio.o

all: create_grd.exe

create_grd.exe: xdriver.cpp $(hds) $(objs)
  $(cc) -o $(exe) $(objs) xdriver.cpp

pth_funs.o: pth_funs.cpp pth_funs.h
  $(cc) -c pth_funs.cpp $(flags)

fio.o: fio.cpp fio.h
  $(cc) -c fio.cpp $(flags)

clean:
  rm -rf *.o

However, upon compilation I get

g++ -c pth_funs.cpp -lpthread
g++ -c fio.cpp -lpthread
g++ -o create_grd.exe pth_funs.o fio.o xdriver.cpp -lpthread
/tmp/ccdaBayB.o: In function `main':
xdriver.cpp:(.text+0x16f): undefined reference to `read_grd(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, grd_str)'
collect2: ld returned 1 exit status
make: *** [create_grd.exe] Error 1

but I have no idea why my main routine can't find read_grd since I believe I am properly defining it and including it. What am I doing wrong?

1 Answer 1

1

Your declaration and definition of read_grd do not have matching arguments. One takes a grd_str as its second argument, the other takes a grd_str&. Since xdriver.cpp includes fio.h, it sees and attempts to use the former function, but the linker can't find a definition for it anywhere. Chances are you want to change your declaration in fio.h to:

void read_grd(std::string, grd_str&);

Now the definition for this function is provided by fio.cpp.

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect solution. I haven't written C++ in a few years, so I'm trying to get back into the swing of things. In another 8 minutes, I will mark this answer as the solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.