Unresolved external symbol when linking to static lib with namespace - c++

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.

Related

namespace extern variable already defined

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.

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.

Static Lib using namespace leads to unresolved external

I am using VS2013 and I have a static lib project with the following header:
#pragma once
namespace StaticLibNamespace
{
void foo( void );
}
Then the function is defined in the cpp as follows:
#include "stdafx.h"
#include "StaticLibHeader.h"
using namespace StaticLibNamespace;
void foo( void )
{
;
}
In my simple console app, I include the reference to StaticLibNameSpaceTest.lib and my main function is the following:
#include "stdafx.h"
#include "..\StaticLibNamespaceTest\StaticLibHeader.h"
int _tmain(int argc, _TCHAR* argv[])
{
StaticLibNamespace::foo();
return 0;
}
If I try and compile this I get the following error:
NamespaceTest.obj : error LNK2019: unresolved external symbol "void __cdecl StaticLibNamespace::foo(void)" (?foo#StaticLibNamespace##YAXXZ) referenced in function _wmain
However if I change my static lib cpp file to the following everything is fine:
#include "stdafx.h"
#include "StaticLibHeader.h"
void StaticLibNamespace::foo( void )
{
;
}
I'm obviously not understanding everything going on with "using namespace" can someone please enlighten me? Thanks!
The using namespace directive changes the lookup rules for symbols when the compiler sees an unqualified name and needs to find what it refers to.
However, in your case, you are defining a new function called foo. As an unqualified name, this defines a new foo in the global namespace (assuming there wasn't already one there). When you qualify the name, you are defining StaticLibNamespace::foo as you intend.
A different solution might be:
namespace StaticLibNamespace {
void foo( void )
{
;
}
} // namespace StaticLibNamespace

I'm having trouble calling a function in my main from another class

I have a main class in which Im trying to call on a function to create the menu but I keep getting this error:
error LNK2019: unresolved external symbol "public: static int __cdecl Controller::menu(void)" (?menu#Controller##SAHXZ) referenced in function _main
This is my main class.
#include "Main.h"
using namespace std;
int main ()
{
Control:: menu();
return 0;
}
this is the Main.h
#pragma once
#include "Control.h"
class Main:
{
public:
Main(void);
~Main(void);
int main();
};
the Control.h:
#pragma once
#include <iostream>
class Control
{
public:
Control(void);
~Control(void);
static int menu ();
};
and finally the control cpp file:
#include "Control.h"
using namespace std;
static int menu ()
{
bunch of menu code
return 0;
}
I think it's something simple but I just cant figure it out. I tried removing static as well as changing the function to a void function, but neither worked.
static int menu ()
{
bunch of menu code
return 0;
}
should be
int Control::menu ()
{
bunch of menu code
return 0;
}
That's the proper way of defining members.
The static function with its prototype should be this way.
int Control :: menu()
{
//bunch of menu code
return 0 ;
}
While you are implementing the class in another file, you have to use the class name with scope resolution operator as well.
You are also having an extra colon at the end of class Main resulting in syntax error.

Error : **** has not been declared

In my Function.h file:
class Function{
public:
Function();
int help();
};
In my Function.cpp file:
#include "Function.h"
int Function::help() //Error here
{
using namespace std;
cout << "Help";
return 1;
}
In my Main.cpp
#include <iostream>
#include "Function.h"
using namespace std;
int menu(){
Function fc;
fc.help();
return 1;
}
int main(int args, char**argv){
return menu();
}
Error is : ‘Function’ has not been declared
Can anybody tell me why? Thank you.
I tried like this and the problem is solved, but I dont really understand why:
In Function.h file:
I use
class Function{
public:
int status;
Function():status(1){}
int help();
};
instead of the old one
class Function{
public:
Function();
int help();
};
All your include statements are missing the #:
#include "Function.h"
^
Everything else looks fine, though you need to also #include <iostream> in Function.cpp since you're using cout.
Here is the Function.cpp that I got to compile and run:
#include "Function.h"
#include <iostream>
int Function::help() // No error here
{
using namespace std;
cout << "Help";
return 1;
}
Function::Function()
{
}
I had a similar problem. Make sure that you only have the required header files. I had two header files both including each other and it spit out this mistake.
You have created a declaration for the constructor of the Function class without including it in your implementation (cpp file).
#include "Function.h"
Function::Function(){
// construction stuff here
}
int Function::help() //Error here
{
using namespace std;
cout << "Help";
return 1;
}
In the first Function.h file you have declared the constructor but not defined it. In the second Function.h file (the one that works) you have defined and declared the Function constructor. You can either define and declare in the header or file, or declare in the header file and define in the Function.cpp file.
For example, declare in the header file "Function.h":
class Function
{
Function();
}
and define here in "Function.cpp":
Function::Function(){}
Or the alternative is to declare and define in the header file "Function.h":
Class Function
{
Function(){}
}
The other thing that you have done in the second version of the header file is to initialise the member variable "status" in the "member initialisation list" which is a good thing to do (See Effective C++ by Scott Meyers, Item 4). Hope this helps :)