namespace extern variable already defined - c++

I cannot compile my C++ program and I don't understand why.
Here's a simple representation of what is throwing errors:
hello/hello.cpp
#include "hello.h"
namespace MyHelloNS {
MyHelloClass::MyHelloClass() {
MyHelloVAR1 = "hi";
MyHelloVAR2 = "dog";
}
}
hello/hello.h
#pragma once
#include <string>
using namespace std;
namespace MyHelloNS {
extern string MyHelloVAR1;
extern string MyHelloVAR2;
class MyHelloClass;
}
class MyHelloNS::MyHelloClass {
public:
MyHelloClass();
};
main.cpp
#include "hello/hello.h"
int main() {
MyHelloNS::MyHelloClass hi1;
}
I get two kinds of errors:
unresolved external symbol in hello.obj
What's wrong?

Add this to main.cpp (or hello.cpp)
namespace MyHelloNS {
string MyHelloVAR1;
string MyHelloVAR2;
}
This question has nothing to do with namespaces, you just aren't following the correct procedure to define a global variable.

Related

undefined reference to method generated as lib .a with CMake

Can you explain me why my function AllToAll is undefined in my example? I use CMake to generate a libNeuralNetwork.a which is called by the exemple.
LayerFactory.hpp
#pragma once
#include "LayerModel.hpp"
#include "Layer.hpp"
namespace nn
{
extern internal::LayerModel AllToAll(int numberOfNeurons, activationFunction activation = sigmoid);
}
LayerFactory.cpp
#include "LayerFactory.hpp"
#include "AllToAll.hpp"
using namespace nn;
using namespace internal;
LayerModel AllToAll(int numberOfNeurons, activationFunction activation)
{
LayerModel model
{
allToAll,
activation,
numberOfNeurons
};
return model;
}
NeuralNetwork.hpp
#pragma once
#include "layer/LayerModel.hpp"
#include "layer/LayerFactory.hpp"
namespace nn
{
class NeuralNetwork
{
public:
NeuralNetwork(int numberOfInputs, std::vector<internal::LayerModel> models);
//...
};
}
Example.cpp
#include "../src/neural_network/NeuralNetwork.hpp"
using namespace nn;
int example1()
{
NeuralNetwork neuralNetwork(3, {AllToAll(5), AllToAll(2)});
}
error message:
CMakeFiles/UnitTests.out.dir/ExamplesTest.cpp.o: In function `example1()':
ExamplesTest.cpp:(.text+0x8b3): undefined reference to `nn::AllToAll(int, nn::activationFunction)'
You have declared AllToAll in the top-level namespace and defined it in the nn namespace.
The following will not declare the function in the namespace:
using namespace foo;
extern void Bar();
You need:
namespace foo {
extern void Bar();
}

Error already defined

Hi i just created a sample class and using it in main but i am getting already defined error.
sample.h
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
#endif
sample.cpp
#include "sample.h"
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
main.cpp
#include <iostream>
#include "sample.h"
using namespace std;
int main(void)
{
int test = count;
return 0;
}
Link error:
main.obj : error LNK2005: "int count" (?count##3HA) already defined in sample.obj
if u see above class i am using #ifndef and #define, actually there things will declare data once thought we include in many places.could some one explain me clearly why its giving that link error.
Remember that #include literally means "add the contents of this file here".
Include guards only protects against a file's content being included more than once per file it's included in.
When the preprocessor has done its preprocessing, this is what your compiler sees:
sample.cpp
[iostream contents here...]
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
main.cpp
[iostream contents here...]
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
using namespace std;
int main(void)
{
int test = count;
return 0;
}
As you can see, there are two definitions of count, one in each file (formally, "translation unit").
The solution is to have a declaration of the variable in "sample.h"
extern int count;
and have the one and only definition in sample.cpp:
int count = 10;
(And you should not put using namespace std; in a header.)
To make a global variable like that visible everywhere:
blah.h
extern int count;
blah.cpp
int count(10);
Include guards only guard against including the same header file multiple times, not against multiple definitions. You should move your variable in a cpp file in order to not violate the ODR, or use internal linkage or declare it external and define it somewhere once. There are multiple solutions depending on the use of that variable.
Notice that I'm ignoring the fact that you probably meant int sample::Get() in the sample.cpp file
#include "sample.h"
sample::sample()
{
cout<<"hello two";
}
int sample::sample() // ??
{
return 10;
}
You have either to declare variable count as having internal linkage as for example
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
namespace
{
int count = 10;
}
//...
#endif
(the above internal declaration valid in C++ 2011) or
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
static int count = 10;
//...
#endif
Or to declare it as having external linkage but define it only once in some module. Fpr example
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
extern int count;
//...
#endif
#include "sample.h"
int count = 10;
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
Otherwise the compiler will issue an error that variable count is defined more than once that is that more than one compilation unit (in this case sample.cpp and main.cpp) contain the variable definition.

Unresolved external symbol when linking to static lib with namespace

I ran into a behavior today that I don't completely understand. I jump right into a minimal code example and will explain along the way.
I have 2 Projects: A static c++ library and a console application.
Static Lib Project:
Library.h
#pragma once
namespace foo
{
int testFunc();
class StaticLibClass
{
public:
static int testMemberFunc();
};
}
Library.cpp
#include "Library.h"
using namespace foo;
// just some functions that don't do much
int testFunc()
{
return 10;
}
int StaticLibClass::testMemberFunc()
{
return 11;
}
Console Application Project:
main.cpp
#include "library.h"
using namespace foo;
void main()
{
// calling this function reslts in LNK2019: unresolved external symbol...
testFunc();
// this function works just fine
StaticLibClass::testMemberFunc();
}
As you can see the static member function of a class works just fine. The single testFunc however results in a linker error. Why is this?
The solution to the problem is to not use "using" in the Library.cpp file but also wrap it in the namespace like so:
Changes that fix the problem:
Library.cpp
#include "Library.h"
namespace foo
{
// just some functions that don't do much
int testFunc()
{
return 10;
}
int StaticLibClass::testMemberFunc()
{
return 11;
}
}
You either need to wrap the body of the implementation functions/methods in a namespace statement that matches the original header, or you can use fully qualified names which is probably better C++ style:
#include "Library.h"
// just some functions that don't do much
int foo::testFunc()
{
return 10;
}
int foo::StaticLibClass::testMemberFunc()
{
return 11;
}
You don't need a using namespace foo; in this version. You are already in the namespace 'foo' when implementing the body's of those two methods, but it can be convenient depending on other types in that namespace.

namespace either undefined or redefined, why?

just a very small program to test how to use the namespace. I divide it into 3 files, since in large product, ns.h is the namespace interface and ns.cpp is the implementation. I cannot put all these stuff into one file.
Here is the code:
//ns.h
#ifndef MY_H
#define MY_H
namespace my
{
int a=1;
int b=0;
void test();
}
#endif
//ns.cpp
#include <iostream>
#include "ns.h"
using namespace my;
//my::a=1;
//my::b=0;
void my::test()
{
std::cout<<a<<std::endl;
}
//testns.cpp
#include <iostream>
#include "ns.h"
int main()
{
std::cout<<my::b<<std::endl;
my::test();
}
If I keep the above code, and compile will get:
testns.obj : error LNK2005: "int my::b" (?b#my##3HA) already defined in ns.obj
testns.obj : error LNK2005: "int my::a" (?a#my##3HA) already defined in ns.obj
If I comment the statement #include "ns.h" I will get undefined error.
D:\mfc\testns.cpp(5) : error C2653: 'my' : is not a class or namespace name
D:\mfc\testns.cpp(5) : error C2065: 'b' : undeclared identifier
D:\mfc\testns.cpp(6) : error C2653: 'my' : is not a class or namespace name
D:\mfc\testns.cpp(6) : error C2065: 'test' : undeclared identifier
Kindly help me if you know how to do this. Thanks a lot.
Headers are for declarations, not definitions. That's nothing to do with the namespace problem.
//ns.h
#ifndef MY_H
#define MY_H
namespace my
{
extern int a, b; // declared, not defined thanks to 'extern'.
void test();
}
#endif
//ns.cpp
#include <iostream>
#include "ns.h"
int my::a=1; // now we provide the actual definitions.
int my::b=0;
void my::test()
{
std::cout << my::a << std::endl;
}
//testns.cpp
#include <iostream>
#include "ns.h"
int main()
{
std::cout << my::b << std::endl;
my::test();
}
You've defined the two variables a and b in ns.h and then the header file is being included in two source files. This violates the one definition rule as the variables are now defined in both the translation units that are including ns.h.
What you need to do is declare variables in the header and define them in a single source file.
To fix the problem, change ns.h to
#ifndef MY_H
#define MY_H
namespace my
{
extern int a;
extern int b;
void test();
}
#endif
In ns.cpp
#include <iostream>
#include "ns.h"
using namespace my;
int my::a=1;
int my::b=0;
void my::test()
{
std::cout<<a<<std::endl;
}
It's not standard practice to define variables in a header file; they are re-defined every time you #include the header, leading to the linker errors that you are seeing.
If you need to share variables between source files (and there's very few good reasons for this), then you should declare them as extern in the header file, and then define them in one of your source files.

"Unresolved External Symbol" errors when creating object in C++

I'm a pretty seasoned programmer but I'm just now diving into C++ and it's... well... more difficult than PHP and Python. I keep having unresolved external errors when trying to create an object from some classes. It's broken up into multiple headers and files but here is a basic idea from one of my classes:
die.h:
#ifndef DIE_H
#define DIE_H
using namespace std;
class Die {
public:
int throwDie();
Die();
};
#endif
die.cpp
#include <iostream>
#include <cstdlib>
#include "Die.h"
using namespace std;
int Die::throwDie()
{
return 0;
}
sixsidedie.h
#ifndef SIXSIDEDIE_H
#define SIXSIDEDIE_H
#include "Die.h"
using namespace std;
class SixSideDie : public Die
{
public:
SixSideDie();
int throwDie();
private:
int randNumber;
};
#endif
sixsidedie.cpp
#include <iostream>
#include <cstdlib>
#include <time.h>
#include "Die.h"
#include "SixSideDie.h"
using namespace std;
const int SIX_SIDE = 6;
int SixSideDie::throwDie()
{
srand((unsigned int)time(0));
SixSideDie::randNumber = rand() % SIX_SIDE + 1;
return SixSideDie::randNumber;
}
main.cpp
#include <iostream>
#include <cstdlib>
#include "Die.h"
#include "SixSideDie.h"
#include "TenSideDie.h"
#include "TwentySideDie.h"
using namespace std;
int main()
{
Die* myDice[3];
myDice[0] = new SixSideDie();
myDice[1] = new TenSideDie();
myDice[2] = new TwentySideDie();
myDice[0]->throwDie();
myDice[1]->throwDie();
myDice[2]->throwDie();
system("pause");
return 0;
}
It keeps telling me that each object I create directly above is an unresolved external symbol and I just don't know why. Any thoughts!?
You declared a constructor for Die but never defined it.
Also, you almost certainly want throwDie to be virtual if you intend to override its behavior in derived classes, and you should never use using namespace std; in a header file (and many people, including me, would argue that you shouldn't use it at file-scope at all).
You didn't define your constructor in your cpp files.
Its good practice to define the constructors of the classes. Check this out:
#ifndef DIE_H
#define DIE_H
using namespace std;
class Die {
public:
int throwDie();
Die() { }; // can you spot the difference here?
};
#endif