سؤال

I have a 3 source files. The main file has a function that use if statements to define a pointer:

main(int dispersalfn) {

if(dispersalfn == 0) {
    kernel1 = flatdisp;
  } else if(dispersalfn == 1) {
    kernel1 = expdisp;
  }

 [...more stuff...]

}

In main.h I have a definition for kernel1:

arma::vec (*kernel1)(arma::vec d, arma::vec m);

In disp.cpp I have definitions for flapdisp and expdisp:

arma::vec flatdisp(arma::vec d, arma::vec m) {
  return m;
}

arma::vec expdisp(arma::vec d, arma::vec m) {
  return (square(m) / (2*M_PI)) % exp(-m % d);
}

disp.h has corresponding definitions for flatdisp and expdisp:

arma::vec flatdisp(arma::vec d, arma::vec m);
arma::vec expdisp(arma::vec d, arma::vec m);

Finally upfun.cpp has a number of functions that call kernel1. The functions in upfun are called by main().

When I compile, I get an error:

 duplicate symbol _kernel in upfun.o and main.o for architecture x86_64

All my header files source each other have include guards, so I don't think that's it. The idea is that when I call main(), I include variables to choose which function is used for kernel1. This worked until I broke up my functions into different files. What causes this error?

هل كانت مفيدة؟

المحلول

I will assume that you meant to say:

duplicate symbol _kernel1 in upfun.o and main.o for architecture x86_64

The linker is complaining that you have defined the symbol (a.k.a. variable) "kernel1" in more than one places.

The problem is that you have defined a variable "kernel1" in a header file main.h. This header file is getting included in more than one .cpp file. Therefore, you have effectively defined "kernel1" in more than one compilation unit.

The solution is simple. Move the definition of "kernel1" to main.cpp instead:

arma::vec (*kernel1)(arma::vec d, arma::vec m);

Update added to address comment:

It was pointed out the symbol "kernel1" is being used from another file as well. In which case,

  1. The definition of "kernel1" still needs to happen in main.cpp as described above.

  2. Add an "extern" declaration of kernel1 in the main.h header file:

    extern arma::vec (*kernel1)(arma::vec d, arma::vec m);
    

This should address your problem.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top