-1

I am trying to include a header file from the book Numerical Recipes in my code. The header files I have to include are the nr3.hpp and the interp_1d.hpp. The interp_1d needs the definitions of nr3 in order to work.

I will write some of the code that appears on interp_1d.hpp so that you get an idea of what I am dealing with with the interp_1d code:

struct Base_interp{
...
};
Int Base_interp::locate(const Doub x){
...
}
...
Doub BaryRat_interp::interp(Doub x){
...
}

There are no header guards in this header file. As a result when I try to input it in multiple other header files I get the error "66 duplicate symbols for architecture x86_64".

The structure of my code is the following:

myPulse.hpp:
#include "nr3.hpp"
#include "interp_1d.hpp"

calc1.hpp:
#include "myPulse.hpp"

calc2.hpp:
#include "myPulse.hpp"

main.cpp:
#include "myPulse.hpp"
#include "calc1.hpp"
#include "calc2.hpp"
#include "nr3.hpp"
#include "interp_1d.hpp"

I don't know how to overcome this issue. I want to be able to use the interp_1d.hpp functions in more than one part of the code. I tried including header guards, but this didn't work:

#ifndef Interp_1d
#define Interp_1d

#endif

Does anyone know how I use the interp_1d header in multiple other headers without this error occurring?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • 2
    How did the preprocessor guards not work? When you tried that, what error(s) did you get? – Chris Oct 04 '21 at 15:03
  • 2
    Sounds like you need to use `inline` on the functions are *defined* (not just *declared*) in the header files, or move the definitions to a .cpp file. – Fred Larson Oct 04 '21 at 15:04
  • @Chris I got the same error as before, it didn't change anything. If you have a look at the Numerical recipes website, many headers are a bit weird, with no guards. I don't know why that is – blindProgrammer Oct 04 '21 at 15:13
  • @FredLarson Right so I prefer not to change the functions themselves, but I will if I have to. If I include the header in the .cpp file of the class myPulse.cpp, I can successfully use it with no issue. However, after this I can't use it in a different .cpp file. I want to be able to use it in multiple .cpp files if possible – blindProgrammer Oct 04 '21 at 15:15
  • Hi Adrian, thank you for the fast reply. I forgot to mention in my question that the myPulse.hpp, calc1.hpp and calc2.hpp all have guards. However, I will give the solution you provided with the myNumRec.hpp a try and see if it fixes the issue. – blindProgrammer Oct 04 '21 at 15:27
  • I have the Second Edition of "Numerical Recipes in C++" (old-fashioned, paper version only) and the header files listed in Appendix A and Appendix B all have header guards. – Adrian Mole Oct 04 '21 at 15:32
  • @AdrianMole Do you have a link to that? Hoppefully that would solve this issue – blindProgrammer Oct 04 '21 at 15:36
  • As I said, it's a paper (printed) version - so no link. Also, I'm not sure that the repo you linked is an official version, or if you should even be including the 'private' headers there in your source code. – Adrian Mole Oct 04 '21 at 15:39
  • There seems to be some confusion here over what these *"66 duplicate symbols for architecture x86_64"* are and how they are included in your project. I shall delete my answer (for now) and maybe undelete/modify it if you can clarify your issue(s). – Adrian Mole Oct 04 '21 at 15:41
  • @AdrianMole I will clarify as best as I understand it. I include interp_1d.hpp in the header file myPulse.hpp. Then I include myPulse.hpp in both calc1.hpp and calc2.hpp. Finally I include all 3 myPulse.hpp, calc1.hpp and calc2.hpp in main.cpp. This leads to the contents of interp_1d being included 3 times and returning an error. Adding guards in interp_1d.hpp doesn't fix the error. What did solve the issue temporarily, is instead of including interp_1d in the myPulse.hpp I included it in the myPulse.cpp. However, when I tried to then include interp_1d in main the same error occured again. – blindProgrammer Oct 04 '21 at 15:55

1 Answers1

0

When working with a single file (or for brevity for books), some code can be simplified, but making multi-file case wrong.

In your case, header guards are missing, and inline are missing (or a cpp file to put definition).

So you cannot use them as-is.

You have either:

  • split code for header/cpp file:

    // interp_1d.hpp
    #pragma once // or include guards
    struct Base_interp{
    //...
    };
    
    //interp_1d.cpp
    #include "interp_1d.hpp"
    Int Base_interp::locate(const Doub x){
    //...
    }
    
    Doub BaryRat_interp::interp(Doub x){
    //...
    }
    
  • or put extra inline/static (not always enough/possible though (globals for example)) and header guard.

    // interp_1d.hpp
    #pragma once // or include guards
    struct Base_interp{
    //...
    };
    
    inline Int Base_interp::locate(const Doub x){
    //...
    }
    
    inline Doub BaryRat_interp::interp(Doub x){
    //...
    }
    
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • I see, I will try spliting it into header/cpp first. This looks promising thank you. If it doesn't work I will try inline method. Will let you know when I give them both a try So generally speaking, structures should be included in the header file while all other functions should be in the cpp code? – blindProgrammer Oct 04 '21 at 16:00
  • splitting is the way to go, if you can, and indeed definition goes in cpp files while declaration goes in header. – Jarod42 Oct 04 '21 at 16:03
  • Yes splitting solved the issue! I've been trying to solve this for 4 days! Thanks a lot for that. So apparently the Numerical Recipes header files have both the .cpp and .hpp content under the same file? Anyway thanks a lot! – blindProgrammer Oct 04 '21 at 16:10