static and extern keywords LINK Error C++ - c++

I have wrote program to test static and extern keywords in C++.
source1.cpp
#include "Header.h"
using namespace std;
static int num;
int main(){
num = 1;
cout << num << endl;
func();
}
source2.cpp
#include "Header.h"
using namespace std;
extern int num;
void func(){
num = 100;
cout << num << endl;
}
Header.h
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
void func();
#endif
When i compile this program it gives me a link error.
error LNK2001, LNk1120 unresolved externals.
What is the reason to causes this Link error?

This Link Error causes because of num variable declared as a static variable.
Even though the variable num is declared as an extern in the source2.cpp file, the linker won’t find it because it has been declared static in source1.cpp.
When you declared variable static, it is local to the file; it has file scope. That variable is unavailable outside of this file.

Related

Defining global variables over multiple files outside main loop

I know it's not very good, but I need global variables across multiple files in my program. These are my graphics window's variables:
Name
Size
Status
.
I know I can make a .h file and declare all variables:
#pragma once
extern std::string GameName;
extern sf::RenderWindow Window;
extern std::string Status;
.
Then I want to define my variables in my main.cpp, so all files can access these values. But I cannot define these unless they are in the int main() loop. Is there another way, so I can define these variables not in main loop?
EDIT
Using Visual Studio 2017.
Errors:
LNK2001 unresolved external symbol "class sf::RenderWindow Window"
(?Window##3VRenderWindow#sf##A) Cubes
Library C:\Users\George\Documents\C++\Files\Libraries\Cubes
Library\Cubes Library\Cubes Library.obj 1
.
LNK2001 unresolved external symbol "class
std::basic_string,class
std::allocator > Status"
(?Status##3V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A) Cubes
Library C:\Users\George\Documents\C++\Files\Libraries\Cubes
Library\Cubes Library\Cubes Library.obj 1
.
LNK1120 2 unresolved externals Cubes
Library C:\Users\George\Documents\C++\Files\Libraries\Cubes
Library\Debug\Cubes Library.dll 1
You can declare them in your main.cpp file, but in order to make them globally accessible, you have to define them outside your main function/loop. If you decalre them inside your main function/loop, they are local variables and cannot (easily) be accessed globally. Doing it this way combined with the header file you suggested will work.
// Global variables...
std::string GameName;
sf::RenderWindow Window;
std::string Status;
int main()
{
return 0;
}
You could also put them in another file, for example globals.cpp.
You would do it like this...
File: Main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#include <string>
extern std::string GameName;
//extern sf::RenderWindow Window;
extern std::string Status;
#endif
File: Main.cpp
#include "stdafx.h"
#include <iostream>
#include "Main.h"
std::string GameName;
//sf::RenderWindow Window;
std::string Status;
extern void foo(); // Function Prototype
int main()
{
GameName = "none";
Status = "none";
foo();
std::cout << GameName << " - " << Status << std::endl;
std::cout << "(HIT A KEY TO CONTINUE)" << std::endl;
getchar();
return 0;
}
File: Other.cpp
#include "stdafx.h"
#include "Main.h"
void foo()
{
// Global variables declared in Main.cpp are now accessible here
GameName = "Horizon New Dawn";
Status = "Finished";
}
This is how to do it using globals in a DLL.
// File: DLLGlobals.h
// This file is used in the DLL project
#ifndef __GLOBALS_H__
#define __GLOBALS_H__
#include <string>
extern "C"
{
extern __declspec(dllexport) std::string GameName;
extern __declspec(dllexport) std::string Status;
}
#endif//__GLOBALS_H__
// File: DLLGlobals.cpp
#include "stdafx.h"
#include "DLLGlobals.h"
extern "C"
{
// Define Global Variables (no C++ mangling)
__declspec(dllexport) std::string GameName = "Dishonored 2";
__declspec(dllexport) std::string Status = "Not Started";
}
// File: DLL.h
#ifndef __DLL_H__
#define __DLL_H__
// This file is included by code using the DLL project
#include <string>
extern "C"
{
__declspec(dllimport) std::string GameName;
__declspec(dllimport) std::string Status;
}
#endif//__DLL_H__
// File: Main.cpp
#include "stdafx.h"
#include <iostream>
#include "Main.h"
#include "<path_to_dll_header>\DLL.h"
int main()
{
std::cout << GameName << ": " << Status << std::endl;
std::cout << "(HIT A KEY TO CONTINUE)" << std::endl;
getchar();
return 0;
}

How to use extern to link to a function in other cpp file?

Here is my main.cpp:
#include <iostream>
#include "function.cpp"
using namespace std;
extern int giveMain();
int main() {
int x = 4;
x = giveMain(x);
cout << x << endl;
}
And here is my function.cpp:
#include <iostream>
using namespace std;
int giveMain(int a) {
a = 3 + a;
return a;
}
But when I compile, it says that "Linker command failed". Can anyone helps me to solve this problem.
You declared the function int giveMain() in main.cpp but the function in function.cpp takes an int. Declare the correct function and it should work. Also extern is the default for functions so you don't need to include the keyword.
EDIT: Just noticed that you #include <function.cpp> in main.cpp. Never include .cpp files. The issue you were having was multiple definitions for int giveMain(int) because the contents of functions.cpp was being compiled twice.

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.

LNK2001 error using extern int

I have this simple example and I can't get it to compile:
Three files: my.h, my.cpp, and use.cpp:
//my.h
extern int foo;
void print_foo();
void print(int);
//my.cpp
#include "my.h"
#include "../../stb_lib_facilities.h" //inlcudes cout, cin, etc
void print_foo(){
cout << foo << endl;
}
void print(int i){
cout << i << endl;
}
//use.cpp
#include <iostream>
#include "my.h"
int main(){
foo = 7;
print_foo();
print(99);
return 0;
}
When I try to compile it I get three errors:
LNK2001: extern "int foo"..
LNK2019: extern "int foo"..
LNK1120:
What am I doing wrong?
Thanks for any help
You do not have any definition of your global variable. In any of your .cpp files, but just in one of them, you should add this:
int foo = 0; // This is a definition
Your declaration:
extern int foo; // This is a declaration
Only tells the compiler that such a global variable exists, but then there is no place where you actually define it. Therefore, the linker will eventually complain that you have an undefined referenced symbol.

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.