Trying something simple with extern - c++

I am trying to learn what "extern" does. I have a simple program where in main's header, a variable is declared with extern. In main, that variable is defined. Main then calls a method in another class file (that includes main's header so it should have access to the external variable), in order to print the value of that variable. But I get a compiler error: "unresolved external symbol "int myglobal". Can someone help? Thanks!
The code runs fine if I remove the reference to this variable in the source.cpp file.
source.cpp
#include "main.h"
#include <iostream>
void printGlobal()
{
std::cout << "Global: " << myglobal;
}
source.h
void printGlobal();
main.h
extern int myglobal;
main.cpp
#include "main.h"
#include "Source.h"
int main()
{
int myglobal = 5;
printGlobal();
system("pause");
return 0;
}

extern only works with global scope. if I say extern int myint; that means there is a file somewhere that has int myint; outside any function this is global scope
there is also file scope which is via static int myint; that means other files won't be able to access it via extern
change main.cpp to
#include "main.h"
#include "Source.h"
int myglobal = 5;
int main()
{
printGlobal();
system("pause");
return 0;
}
for file scope
#include "main.h"
#include "Source.h"
static int myglobal = 5;
int main()
{
printGlobal();
system("pause");
return 0;
}

extern and static keywords are storage specifiers. Each storage specifiers basically add two properties to a name:
1. Allocation or deallocation of name.
2. Visiblity.
If you add "extern" keyword to name in "C", it only declares a variable so that you can use that name in your program without compiler error. Means extern variable are visible outside the scope where they are defined. This symbol also instructs the linker to find the symbol definition in other object files. Therefore in your case when you added "extern" to myGlobal, you only declared a variable with name "myGlobal " and could use that name in your program. But when linker came, it tried to find the place where that "myGlobal" is defined, but it was unable to find this and gave you "unresolved external symbol" error.
All extern(global) variables are allocated when the program starts and destroyed when program ends.
Another use of "extern" other than what A.H. provided:
test1.c
int myextern = 10;
test2.c
void func1(){
int extern myextern;
printf("%d",myextern);
}
Static:
Allocation/Deallocation of static variables are same as extern variable. Means they are allocated when the program starts and destroyed when program finished. But visibility of the static variables are limited to the lexical scope where they are declared. They are not visible outside their scope.

Related

Identification problem in variables belonging to extern storage class

a.cpp
extern int var;
int func(){
return var;
}
main.cpp
#include <iostream>
using namespace std;
extern int func();
int main(){
int var = 12;
cout << func();
}
When I write as above, I get this error "undefined reference to var".
a.cpp
extern int var;
int func(){
return var;
}
main.cpp
#include <iostream>
using namespace std;
extern int func();
int var = 12;
int main(){
cout << func();
}
But when I make the above change in the main.cpp file, the application compiles without any problems and 12 is printed on the screen.
Why does this problem occur?
Well, you never know if it's a troll, but in short, your first set of functions declare var as a local variable, within the scope of main() only. As such you may not reference it in a.cpp. Imagine if you did... the lifetime of var is (strictly) temporary (irrespective of being in the "main" function) and is not reserved in RAM, and as such the compiler will not allow the use of extern in a.cpp... what address could it use?
The second time you correctly declare var as a global, within main.cpp. As such your extern in a.cpp is valid, and you can thus reference var. In this case var is reserved in RAM, and accessible from files that declare it extern.
A good explanation of scope is available at tutorialspoint, and here at cplusplus.
In the first case, the variable is local to function main(). You cannot reference such local variables from other functions.
In the second case it is a global variable. That works.

Why to add "extern" keyword if the global variable is external by default?

main.cpp
#include <iostream>
extern int g_x; // this extern is a forward declaration of a variable named g_x that is defined somewhere else
int main()
{
std::cout << g_x; // prints 2
return 0;
}
add.cpp
int g_x { 2 };
If I delete extern in main.cpp, then the code does not work. One the other hand, I don't need extern in add.cpp. Global variables are external by default, but still. Is it because external linkage is a "one-sided relation" between two entities that are linked in different files?
extern is different from external linkage. extern just means that you do a declaration, and that the variable is defined somewhere else.
If you remove extern, int g_x will be defined in main.cpp violating ODR (since you have it defined twice).

Can we define a variable having extern storage class associated with it?

I was reading about extern storage class from this website:
https://www.geeksforgeeks.org/understanding-extern-keyword-in-c/
and there is this example:
#include "somefile.h"
extern int var;
int main(void)
{
var = 10;
return 0;
}
Supposing that somefile.h has the definition of var
Since we cannot define the variable which is an extern storage class how is it working correctly?
Does it mean that if an extern variable is already defined somewhere in the script and then if I re-define it any further in my code it's going to work?
C Language has methodology :- first Declare it and define it as you know daily use in C. You declare a function and define it somewhere downside.
The Main things is declaring a variable doesn't allocate memory. Memory is only allocated once you define it and in this case var is declare as well defined in somefile.h Memory is allocated via that file only and in this example extern states that this variable is defined somewhere else and Memory is already initialized for it.
[blog]: https://errbits.com/2021/12/16/storage-classes-in-c/ "Storage Classes in C"
And while compile time compiler verify that for same ,if var is already defined in somefile.h it will compile without error since it will check its symbol table to verify if it there.
The keyword extern means external linkage. The below given example gives some basics about extern usage.
someclass.h
#pragma once
extern int var; //this DECLARES an GLOBAL int variable named var with EXTERNAL LINKAGE
In the above someclass.h, we have declared a global int variable named var with External linkage. This means we will be able to use this variable from other files.
someclass.cpp
#include "somefile.h"
int var = 10; //this DEFINES the GLOBAL int variable named var that was DECLARED inside somefile.h with external linkage
In the above file someclass.cpp we have defined the global variable named var that was declared in file somefile.h.
main.cpp
#include "somefile.h"
#include <iostream>
int main(void)
{
std::cout<< var<<std::endl; //prints 10
return 0;
}
In the above file main.cpp we've used(printed on console) the global variable named var without defining it in main.cpp. This is possible because the variable var as i said has external linkage.
The output of the program can be seen here.

Difference between defining globally and within scope

So, I have a variable declared globally. For it to be used, it has to be defined. I get different results based on whether I define it globally or within scope of the main function.
Here's the basic code:
// main.cpp
//int variable = 3;
int main()
{
//int variable = 5;
func();
return variable;
}
// source.cpp
#include "source.hpp"
void func()
{
cout << variable << endl;
}
// source.hpp
#ifndef __SOURCE_HPP_INCLUDED__
#define __SOURCE_HPP_INCLUDED__
#include<iostream>
using namespace std;
extern int variable;
void func();
#endif // __SOURCE_HPP_INCLUDED__
So, if I define globally (outside main), then everything works. But if I define within main, then I get "undefined reference to 'variable'" errors. But I only call upon source.cpp when I'm inside main; so why do I get this error, if variable is defined within the same "scope" as func? Is it the compiler just preemptively giving the error before linking is done? Or is it related to the fact that I declared it as "extern"?
You can't define a global variable inside a function. You're actually defining a different, unrelated local variable that just happens to have the same name.
func references the global variable, so you must have a definition for it.

When to use extern in C++

I'm reading "Think in C++" and it just introduced the extern declaration. For example:
extern int x;
extern float y;
I think I understand the meaning (declaration without definition), but I wonder when it proves useful.
Can someone provide an example?
This comes in useful when you have global variables. You declare the existence of global variables in a header, so that each source file that includes the header knows about it, but you only need to “define” it once in one of your source files.
To clarify, using extern int x; tells the compiler that an object of type int called x exists somewhere. It's not the compilers job to know where it exists, it just needs to know the type and name so it knows how to use it. Once all of the source files have been compiled, the linker will resolve all of the references of x to the one definition that it finds in one of the compiled source files. For it to work, the definition of the x variable needs to have what's called “external linkage”, which basically means that it needs to be declared outside of a function (at what's usually called “the file scope”) and without the static keyword.
header:
#ifndef HEADER_H
#define HEADER_H
// any source file that includes this will be able to use "global_x"
extern int global_x;
void print_global_x();
#endif
source 1:
#include "header.h"
// since global_x still needs to be defined somewhere,
// we define it (for example) in this source file
int global_x;
int main()
{
//set global_x here:
global_x = 5;
print_global_x();
}
source 2:
#include <iostream>
#include "header.h"
void print_global_x()
{
//print global_x here:
std::cout << global_x << std::endl;
}
It is useful when you share a variable between a few modules. You define it in one module, and use extern in the others.
For example:
in file1.cpp:
int global_int = 1;
in file2.cpp:
extern int global_int;
//in some function
cout << "global_int = " << global_int;
It's all about the linkage.
The previous answers provided good explanations about extern.
But I want to add an important point.
You ask about extern in C++, not in C and I don't know why there is no answer mentioning the case when extern comes with const in C++.
In C++, a const variable has internal linkage by default (not like C).
So this scenario will lead to linking error:
Source 1 :
const int global = 255; //wrong way to make a definition of global const variable in C++
Source 2 :
extern const int global; //declaration
It needs to be like this:
Source 1 :
extern const int global = 255; //a definition of global const variable in C++
Source 2 :
extern const int global; //declaration
This is useful when you want to have a global variable. You define the global variables in some source file, and declare them extern in a header file so that any file that includes that header file will then see the same global variable.