3

I am trying to access variables and functions defined in a namespace in a header file. However, I get the error: xor.cpp:(.text+0x35): undefined reference to "the function in header file" collect2: error: ld returned 1 exit status. It seems to me that the compilation steps are OK after reading this post, and also because I can access variables in this header file, but calling the function returns the error mentioned above. My question is: How can I access those functions in the namespace from my main.cpp ? What am I doing wrong ?

The case with a class is clear to me, but here I don't understand because I am not supposed to create an object, so just calling the namespace in front should be OK (?).

Edit

After changes suggested by Maestro, I have updated the code the following way, but it still doesn't work. The error I get is the same. If I define using NEAT::trait_param_mut_prob = 6.7; I get the error: xor.cpp:127:36: error: expected primary-expression before ‘=’ token

Main c++

#include "experiments.h"
#include "neat.h"
#include <cstring>

int main(){

  const char *the_string = "test.ne";
  bool bool_disp = true;
  NEAT::trait_param_mut_prob;
  trait_param_mut_prob = 6.7;
  NEAT::load_neat_params(the_string ,bool_disp);
  std::cout << NEAT::trait_param_mut_prob << std::endl;
  return 0;
}

neat.h

    #ifndef _NERO_NEAT_H_
    #define _NERO_NEAT_H_
    
    #include <cstdlib>
    #include <cstring>
    
    namespace NEAT {
        extern double trait_param_mut_prob;
        bool load_neat_params(const char *filename, bool output = false); //defined HERE 
    
    }
    #endif

neat.cpp

#include "neat.h"
#include <fstream>
#include <cmath>
#include <cstring>

double NEAT::trait_param_mut_prob = 0;

bool NEAT::load_neat_params(const char *filename, bool output) { 
                    //prints some stuff
                    return false;
                    };

Makefile

neat.o: neat.cpp neat.h
        g++ -c neat.cpp
halfer
  • 19,824
  • 17
  • 99
  • 186
Joachim
  • 490
  • 5
  • 24
  • 5
    Where is the `#endif` in header? – Maestro Jan 29 '20 at 18:44
  • This doesn’t address the question, but names that begin with an underscore followed by a capital letter (`_NERO_NEAT_H_`) and names that contain two consecutive underscores are reserved for use by the implementation. Don’t use them in your code. – Pete Becker Jan 29 '20 at 19:03
  • @Maestro indeed I forgot to copy the #endif in the post, but it is in the code – Joachim Jan 29 '20 at 20:31
  • @PeteBecker Thank you for the remark. What I am actually trying to do here is to modify a package which I downloaded, so there is no problem with those _NERO_NEAT_H_ – Joachim Jan 29 '20 at 20:33
  • @Joachim — downloading a file doesn’t exempt it from the rules. That identifier is reserved for use by the implementation. – Pete Becker Jan 29 '20 at 20:36

1 Answers1

-1

You are breaking the "ODR rule" (One-Definition-Rule): you've defined trait_param_mut_prob and load_neat_params twice once in source file neat.cpp and second in main.cpp so simply remove those lines from main.cpp:

//double NEAT::trait_param_mut_prob; //NEAT is the namespace 
//bool NEAT::load_neat_params(const char* filename, bool output); //function defined in the namespace 
  • Add #endif in you header neat.h.
  • to make your function and variable available in main just use using or fully-qualify the call because as I've seen you intend to re-declare them in main to avoid fully qualifying them: in main:

    int main()
    {
    
        using NEAT::trait_param_mut_prob;
        using NEAT::load_neat_params;
    
        const char* the_string = "test.ne";
        bool bool_disp = true;
        trait_param_mut_prob = 6.7;//works perfectly 
        load_neat_params(the_string, bool_disp);
        // or fully-qualify:
    
        //NEAT::load_neat_params(the_string, bool_disp);
        //NEAT::trait_param_mut_prob = 6.7;//works perfectly 
    }
    
  • Also it is erroneous that your function load_neat_params doesn't return a bool value. So make it either return true or false.

Maestro
  • 2,512
  • 9
  • 24
  • It still doesn't work. I have tried both options. Either fully qualifying or with using, I still get the same error: `g++ xor.cpp /tmp/cccl2MH9.o: In function main: xor.cpp:(.text+0x23): undefined reference to NEAT::trait_param_mut_prob' xor.cpp:(.text+0x35): undefined reference to NEAT::load_neat_params(char const*, bool) xor.cpp:(.text+0x3c): undefined reference to NEAT::trait_param_mut_prob' collect2: error: ld returned 1 exit status `. I will update the code – Joachim Jan 29 '20 at 20:24
  • Actually, only by calling the following way: `using NEAT::trait_param_mut_prob = 6.7` I get `xor.cpp:127:36: error: expected primary-expression before ‘=’ token` which, again I don't understand why – Joachim Jan 29 '20 at 20:41
  • No! Remove assignment: `= 6.7` so it becomes: `using NEAT::trait_param_mut_prob;`. – Maestro Jan 29 '20 at 20:47
  • Excuse the stupid question, but what do you mean exactly by adding the source to the project ? It is compiled with Ubuntu 18.04 – Joachim Jan 29 '20 at 20:47
  • What compiler are using? Your program works fine with me. – Maestro Jan 29 '20 at 20:47
  • I'm using g++, I compile first with the makefile and then compile the main cpp with the simple command `g++ xor.cpp`. I tried removing the `=6.7` as you mentioned but still get the same error mentioned above – Joachim Jan 29 '20 at 20:50
  • Are you specifying `C++11`? – Maestro Jan 29 '20 at 20:50
  • No but I have tried with the `-std=c++11` but it didn't change anything. Also I have updaetd the code removing `=6.7` in the `using` – Joachim Jan 29 '20 at 20:53
  • First I compile with the command `make` in the terminal and then execute with the exact command `g++ -std=c++11 xor.cpp`. Also all the files are in the same folder – Joachim Jan 29 '20 at 20:56
  • where is `neat.cpp`? – Maestro Jan 29 '20 at 20:56
  • `neat.cpp`is in the makefile in order to get the object file `neat.o`, if my understanding is correct – Joachim Jan 29 '20 at 20:57
  • Try it without make file from a terminal. – Maestro Jan 29 '20 at 20:59
  • 2
    Try this from terminal: `g++ neat.cpp main.cpp -o prog`. – Maestro Jan 29 '20 at 21:01
  • I am so sorry. Please google on how to set your makefile. Accept as an answer if it helps. – Maestro Jan 29 '20 at 21:04
  • Indeed there must be a problem there. Still, I have always done this for classes and never had problems. Could you perhaps give me a hint about where is the problem in the makefile ? – Joachim Jan 29 '20 at 21:06
  • Excuse me. now I am not on gcc but i'm using MSVC. – Maestro Jan 29 '20 at 21:08
  • You are welcome! Happy for having it worked for you! – Maestro Jan 29 '20 at 21:10