Accessing elements in namespace defined in header file - c++

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

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.

Related

Undefined reference using namespace C++

When I want to run the code the compiler says undefined reference to math::calc
I read questions and answers about this problem at StackOverflow and it do not help me solve my problem.
Comp.h
#include <utility>
namespace math {
typedef std::pair<double,double> Comp;
double getFirst(Comp a);
...
}
Comp.cpp
#include "comp.h"
namespace math {
double getFirst(Comp a) {
return a.first;
}
...
}
Comp file: every function return Comp or double. I call function from cal.cpp file several times
cal.h
#include "comp.h"
#include "helper.h"
namespace math {
Comp calc(const string& str);
...
}
cal.cpp
#include "eval.h"
namespace math {
Comp calc(const string& str) {
...
}
}
Cal file: Some functions return with comp type, not just the cal function.
helper.h
namespace math {
...
}
helper.cpp
#include "helper.h"
namespace math {
...
}
helper file just contains few function that I calling from cal.cpp file. Each function is calling several times.
main.cpp
#include "calc.h"
int main() {
string str = " ";
pair<double,double> res = math::calc(str);
cout << res.first << " " << res.second << endl;
return 0;
}
In the whole project, I do not use any classes.
I included every file that I calling except the c++ original file.
I use the std namespace in each file but I do not write it here.
I absolutely no idea what could be the problem with my code.
If I also include cal.cpp in the main.cpp the code editor says undefined reference to each file that I calling from helper.h. I do not want to include cal.cpp in the main file I just mentioned it
You have to compile all your project's *.cpp files and then link them (results of compilation) properly - the linking process depends on the environment/IDE you're using, just look it up. If you're not linking it properly the final executable wont have all the functions definitions that requires, hence getting undefined reference.

c++: how to access variables in the same namespace but defined in a different file?

Consider the following two files:
a.cpp:
#include <string>
namespace a
{
const std::string str = "something";
}
b.cpp:
#include <iostream>
#include <string>
namespace a
{
extern const std::string str;
}
int main(int argc, char **argv)
{
std::cout << a::str;
return 0;
}
When I compile them, thusly (Fedora 30, gcc 9.2.1):
g++ a.cpp b.cpp -o a
I get linker errors:
/usr/bin/ld: /tmp/ccEtAgEb.o: in function `main':
b.cpp:(.text+0x10): undefined reference to `a::str[abi:cxx11]'
collect2: error: ld returned 1 exit status
Anyone able to tell me why, and how to fix it? I wanted to avoid putting a reference to a::str in a header file, since it's not part of the public interface, but rather a private variable within my namespace.
const std::string str = "something";
should be
extern const std::string str = "something";
const qualifying objects at namespace scope has the additional property of imposing internal linkage on their name. Your original code is the same as
static const std::string str = "something";
Try to add #include "a.cpp" into b.cpp.
Then you code will be correct, with extern definition in b and implementation in a.

Declare variable in namespace, define it in main, make it visible to all other files [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 years ago.
Using C++14, I'm trying to define a variable in a namespace where commonly used variables are stored (App::Common). The main function should be the one that sets it, since it gets set to argv[0]. Meanwhile I need the variable to be visible by all other classes/files. But I get the linker error shown below. Also, ideally I would like the variable to be const where only the main function would set it once.
common.hpp
#pragma once
#include <string>
namespace App{
namespace Common{
extern std::string appPath;
}
}
main.cpp
#include "common.hpp"
#include "client.hpp"
#include <string>
int main() {
App::Common::appPath = argv[0];
}
client.hpp
#include "common.hpp"
class Client {
public:
void printAppPath();
};
client.cpp
#include <iostream>
#include <string>
#include "common.hpp"
#include "client.hpp"
void Client::printAppPath() {
std::cout << App::Common::appPath << std::endl;
}
I get the following error by the linker:
ld: main.o: in function `main':
main.cpp:(.text.startup.main+0x25): undefined reference to `App::Common::appPath[abi:cxx11]'
ld: Client.o: in function `Client::printAppPath()':
Client.cpp:(.text...): undefined reference to `App::Common::appPath[abi:cxx11]'
This
#pragma once
#include <string>
namespace App{
namespace Common{
extern std::string appPath;
}
}
contains only declaration of the variable appPath without its definition.
Here
#include "common.hpp"
#include "client.hpp"
#include <string>
int main() {
App::Common::appPath = argv[0];
}
there is used the assignment operator to assign a value tp the variable appPath as if it were already defined. However actually its definition does not yet exist.
You can define the variable in any module in any enclosing namespace of the namespace Common or inside the namespace. For example you could define it in client.cpp like
std::string App::Common::appPth;
You are mixing definition and assignment, which are two different things for a variable:
a declaration for a variable x tells your compiler that there exists somewhere a variable named x;
a definition for a variable x tells your compiler that it needs to reserve some space for this variable x, and that the variable x will live at this location;
an assignment assigns a value to a variable.
For a variable, a declaration is usually a definition:
void foo() {
int a; // Declaration AND Definition!
}
...except when the variable is marked as extern, since extern explicitly tells the compiler that this variable is defined elsewhere. In your case, this:
namespace App::Common { // C++17 style
extern std::string appPath;
}
...is a declaration, but this:
namespace App::Common { // C++17 style
std::string appPath;
}
...would be a definition (and also a declaration), and this:
int main(int argc, char *argv[]) {
App::Common::appPath = std::string(argv[0]);
}
...is an assignment.
You should not define appPath in a header such as common.hpp, otherwize, you will have multiple definitions of the same variable (one for each .cpp file that includes your common.hpp) and the program will fail to compile.
What you want is a single definition for your program, and the only way to obtain it is to define App::Common::appPath once-and-for-all in a .cpp file. You can define it in main.cpp if you want:
#include <string>
#include "common.hpp"
#include "client.hpp"
// Definition:
std::string App::Common::appPath;
int main() {
// Assignment:
App::Common::appPath = argv[0];
}
You need definition:
in Common.cpp:
namespace App{
namespace Common{
std::string appPath;
}
}

C++ undefined reference to class (1 header 2 cpp's)

I am reading a book (C++ for dummies) as well as watching youtube videos to learn how to code. I am currently struggling with very simple class functions.
Main.cpp
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include "Test.h"
using namespace std;
int x;
int main(int nNumberofArgs, char* pszArgs[])
{
combat fight;
cout << x;
fight.dodmg();
cout << x;
return 0;
}
Test.h my header file with the class
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
using namespace std;
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
class combat
{
public:
int dodmg();
void zero_out();
private:
int x;
};
#endif // TEST_H_INCLUDED
Test.cpp class functions
#include "Test.h"
int combat::dodmg()
{
x = x - 5;
return x;
}
void combat::zero_out()
{
x = 20
}
I tried to make this very simplistic just to figure out how to work a class.
I included a lot of #includes just to try and make sure it wasn't something stupid like I needed strings.
I am not sure why but the videos I watched simply had the header say
ifndef TEST_H (of their respective code, mine has an _INCLUDE as well, I tried deleting it and it still didn't work.
My unfortunate errors
on line 14 of main.cpp fight.dodmg(); it says
\Beginning_Programming-CPP\Playing_with_class\main.cpp|14|undefined reference to `combat::dodmg()'|
then below that
||error: ld returned 1 exit status|
How are you compiling this? I think this is an issue because you arent compiling your Test.cpp file. If you arent already, try compiling with the command:
g++ main.cpp Test.cpp -o MyProgram
UPDATE:
Few things, you dont have a closing statement to your #ifndef directive in Text.h, you will need a constructor to set the value of x so i added one to the combat class also you were missing a semicolon in the zero_out function. I added comments to all the lines I changed.
Okay try this:
Test.h
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
using namespace std;
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
class combat
{
public:
combat(); // added constructor
int dodmg();
void zero_out();
private:
int x;
};
#endif // closed #ifndef
Text.cpp
#include "Test.h"
combat::combat() // implemented constructor
{
x = 20;
}
int combat::dodmg()
{
x = x - 5;
return x;
}
void combat::zero_out()
{
x = 20; // added ';'
}
Hope this helps,
Final edit: I dont think you really need your header guards in this scenario, you could remove the "#ifndef, #define, and the #endif" lines and not see a difference really
It sounds like you provide the wrong arguments for the compiler. Your header file (Test.h) simply provides signatures for the methods, but the implementations are given in the source file (Test.cpp).
This is an important part of writing C++ (or C) code. Your compiler does not automatically search for source files, so you need to tell it where to look, e.g.:
g++ -std=c++11 main.cpp Test.cpp -o main

error: expected `;' before '{' token - What is the cause?

Here is my implementation file:
using namespace std;
#include <iostream>
#include <iomanip>
#include <string>
#include <stack> //line 5
#include "proj05.canvas.h"
//----------------Constructor----------------//
Canvas::Canvas() //line 10
{
Title = "";
Nrow = 0;
Ncol = 0;
image[][100]; // line 15
position.r = 0;
position.c = 0;
}
//-------------------Paint------------------// line 20
void Canvas::Paint(int R, int C, char Color)
{
cout << "Paint to be implemented" << endl;
}
The errors I'm getting are these:
proj05.canvas.cpp: In function 'std::istream& operator>>(std::istream&,
Canvas&)':
proj05.canvas.cpp:11: error: expected `;' before '{' token
proj05.canvas.cpp:22: error: a function-definition is not
allowed here before '{' token
proj05.canvas.cpp:24: error: expected `}' at end of input
proj05.canvas.cpp:24: error: expected `}' at end of input
These seem like simple syntax errors, but I am not sure what's wrong. Could someone decode these for me? I'd really appreciate it, thanks for your time!
EDIT
Here is the definition of Canvas in my .h file:
#ifndef CANVAS_H
#define CANVAS_H
#include <iostream>
#include <iomanip>
#include <string>
#include <stack>
class Canvas
{
public:
Canvas(); void Paint(int R, int C, char Color);
const int Nrow;
const int Ncol;
string Title;
int image[][100];
stack<int> path;
struct PixelCoordinates
{
unsigned int r;
unsigned int c;
} position;
};
#endif
"proj05.canvas.h" i bet the problem is there. may be no ; after class def
You must use initializer list to initialize const-members
Try this:
#include <iostream>
#include <iomanip>
#include <string>
#include <stack> //line 5
#include "proj05.canvas.h"
using namespace std;
//----------------Constructor----------------//
Canvas::Canvas():Nrow(),Ncol() // Initializer list
{
Title = "";
//initialize image[][] correctly, your way is syntactically incorrect
position.r = 0; //correction here
position.c = 0; // and here
}
//-------------------Paint------------------// line 20
void Canvas::Paint(int R, int C, char Color)
{
cout << "Paint to be implemented" << endl;
}
Few things:
1
PixelCoordinates.r = 0;
PixelCoordinates.c = 0;
should be:
position.r = 0;
position.c = 0;
2
image has already been declared. What is this:
image[][];
It sounds like you forgot to put a semicolon after your class definition. Look in "proj05.canvas.h". You should see something like:
class Canvas{
...
};
One thing that catches my eye as wrong/weird is image[][]. That does not really do anything. Also, I do not believe you can assign to constant member outside of a ctor list.
Finally, your assignment to PixelCoordinates is completely in error. You've created a local struct definition, but have not made a member that uses it, therefore you cannot assign anything at all to it - especially the struct's title. That would really confuse a compiler.
Yikes.
(Not an answer to your specific problem, but...)
You should also remove the
using std;
That has no business in a .h file.
I am going to guess the oddly formatted .h file may be a problem. It is legal for a filesystem of course, but it could be that. Also ensure you have the ending semicolon on the class.
You need to have both dimensions filled in for the array you have (probably a horrible design to use that int he class anyway...)
Whatever the reason for other errors is, the memeber definition int image[][100] is illegal. Non-static data members of the class cannot be declared with incomplete types. All dimensions of an array must be specified explicitly.