Confusion about the extern keyword and multiple source files - c

I am trying to fully understand how extern works, so I created 3 files, two of them are source files and the last is a header file. This is what is contained in each of them:
testingfile1.c
#include <stdio.h>
#include "testingheader.h"
int main() {
change();
int my_extern;
printf("\n%d", my_extern);
return 0;
}
testingfile2.c:
#include <stdio.h>
#include "testingheader.h"
void change() {
int my_extern;
my_extern = 15;
printf("%d", my_extern);
}
testingheader.h:
#if !defined(TESTINGHEADER_H)
#define TESTINGHEADER_H
#include <stdio.h>
extern int my_extern;
void change();
#endif
The output of this program is: 15 0. However, I thought that since my_extern is an extern int, if you were to change to the value in one source file, it's value would be changed in all of the other source files. Is this not how extern works, or am I doing something wrong in the code itself?

In both cases remove int my_extern; where you have it, because those become local variables which happen to have the same name my_extern.
extern int my_extern; just means there's an int called my_extern "out there somewhere". So you'd have to declare int my_extern somewhere at file scope, for example like this:
int my_extern = 0;
void change() {
my_extern = 15;
printf("%d", my_extern);
}

In testingfile2.c, the my_extern variable is local to the function and you are not seeing the global my_extern that the extern command is referencing. Of course, you don't have a global my_extern, so that is another problem. You would get a linker error if you actually tried to reference the global my_extern that the extern command is referencing.

The issue is you're re-declaring int my_extern; inside your functions. Therefore, C treats that as a separate variable from the global my_extern.
The statement extern int my_extern; is a declaration that a global int called my_extern will be declared somewhere. You haven't done that. Instead, you've created local my_extern variables.

Related

How to globaly initialize variable in c and what is the difference between static and extern?

please explain me about how a variable scope can be globally initialized in C and what is the difference between static and extern
The scope of variable means: Where can it be seen (aka where does it exist) and thereby be accessed.
The scope of a variable depends on where in the code it is defined.
A variable gets global scope when it is defined outside a function. The keyword static can limit the scope of a global variable so that it can only be seen in that particular c-file (aka compilation unit). So:
file1.c
int gInt1; // Global variable that can be seen by all c-files
static int gInt2; // Global variable that can be seen only by this c-file
void foo(void)
{
int lInt; // Local variable
...
}
In order to use a global variable from another c-file, you tell the compiler that it exists in some other file. For this you use the extern keyword.
file2.c
extern int gInt1; // Now gInt1 can be used in this file
void bar(void)
{
int n = gInt1 * (gInt1 + 1);
...
}
You often put the extern declaration into a header file. Like:
file1.h
extern int gInt1; // Any c-file that includes file1.h can use gInt1
file2.c
#include "file1.h" // Now gInt1 can be used in this file
void bar(void)
{
int n = gInt1 * (gInt1 + 1);
...
}
Regarding initialization
Initializing a global variable is no different from initializing a local variable.
The only difference between global and local variables is when you do not have an initializer. In such cases a local variable will be left uninitialized while global variables will be default initialized (which typically means initialized to zero).
file1.c
int gInt1 = 42; // Global variable explicit initialized to 42
int gInt2; // Global variable default initialized to 0
void foo(void)
{
int lInt1 = 42; // Local variable explicit initialized to 42
int lInt2; // Local variable uninitialized. Value is ??
...
}
To Declare a variable of global scope ,just declare it outside all functions.
Intial value -0.
Scope of Global variable: It can be used in all functions and files.
Life- Till Program execution.
Use of extern keyword:
If you declared a global variable in a file and want to use it in another file then extern keyword is used.
int x=5; //source file
extrern int x=10; //any other file
Another use of extern keyword is if the golbal variable is used before declaration in program.
example:
void main()
{
int x
extern int y;
x=y;
}
int y=5;
Static varialbe:
intial value-0
scope- Till control remain in block,function or file.
Life -Till Program execution.
void main()
{
fun();
fun();
fun();
}
void fun()
{
int x=0;
x++;
}
After Program ends x=3.
Static Variable can also be used as global variable and declared outside all functions
but the scope remain in the file in which it is defined.
example:
static int x=2;
int main()
{
x=5;
}
That's all!

Understanding how extern works

The way I understand extern is that we are able to declare a variable anywhere in a program and use it, but we can just define it once. I am getting an error in the following program.
hello.c
#include <stdio.h>
#include "function.h"
extern int c;
int main()
{
int c;
c=10;
printf("%d\n",c);
printExternValue();
return 0;
}
function .h
void printExternValue();
function .c
#include "function.h"
#include "stdio.h"
extern int c;
void printExternValue()
{
printf("%d\n",c);
}
I expect this program to print out:
10
10
But it's not doing so since it's giving an error. I re-declared the variable c in the function.c file with the intention of using the value that is stored in the so called external storage.
Error: function.c:(.text+0x6): undefined reference to `c'
I am currently reading a PDF file from tutorialspoints which I think to be very redundant since the intention of creating a variable with the aggregate extern is useless. The right way this should be done is that they define the variables outside the function is that right?
#include <stdio.h>
// Variable declaration:
extern int a, b;
extern int c;
extern float f;
int main ()
{
/* variable definition: */
int a, b;
int c;
float f;
/* actual initialization */
a = 10;
b = 20;
c = a + b;
printf("value of c : %d \n", c);
f = 70.0/3.0;
printf("value of f : %f \n", f);
return 0;
}
Variable declread as
extern int c;
is an external declaration that potentially requires an external definiton. "External" in this case means "located outside of any function". Your c declared locally in main() does not fullfill that role.
Since you are using that externally declared variable c in your code you have to define it and define it only once.
You need
int c;
or
int c = 0;
or
extern int c = 0;
it one of your implementation files, at file scope. All of these are definitions. Any of them will define your variable.
Define your variable once in one of your files (to reserve space),
int c = 0;
Declare your variable references everywhere else (in all of your other files) (to reference said space),
extern int c;
But that could be confusing, so name them indicative of the 'global' use,
int glob_a, glob_b;
int glob_c;
float glob_f;
And declare your variable references everywhere else,
extern int glob_a, glob_b;
extern int glob_c;
extern float glob_f;
But you really want to avoid littering you namespace, so when you have a collection of globals, declare a struct that contains them (in a header file probably called globals.h),
typedef struct globals_struct {
int a, b;
int c;
float f;
} globals_t;
And once (in your file main.c that declares main()), you define the struct,
#include globals.h
globals_t globs;
And everywhere else, reference the space,
#include globals.h
extern globals_t globs;
Often, you will see a stanza such as this, where MAIN is only declared in one file,
#ifndef MAIN
extern globals_t globs;
#else
globals_t globs;
#endif
Use your globals,
int my_a = globs.a;
int my_b = globs.b;
int my_f = globs.f;
Notice how you have avoided needless namespace pollution?
Because extern just tells the compiler (actually the linker) that a variable is being defined elsewhere and needs to be linked against.

C: Passing variables between files

I'm trying to pass a local variable (in func1) to a function (func2) in another file, but func2 requires that as a global variable. To explain things better, here are the two files:
file1.c:
#include <something.h>
extern void func2();
void func1(){
int a=0;
func2();
}
file2.c:
#include <something.h>
extern int a; //this will fail
void func2(){
printf("%d\n",a);
}
The variable int a can't be declared as global in file1, as func1 is called recursively. Is there a better way to do this?
In file1.c:
#include <something.h>
#include "file1.h"
int a;
void func1(){
a = 0;
}
In file1.h
extern int a;
In file2.c:
#include <something.h>
#include "file1.h"
void func2(){
printf("%d\n",a);
}
So:
The variable is in file1.c
file1.h allows others to know that it exists and its type is int.
file2.c includes file1.h so that the compiler knows about var a existence before file2.c tries to use it.
Sorry I can’t comment on Ciro Pedrini’s answer, so I would say: do as he says, but also:
Make the argument list of func1 explicitly (void) (and set your compiler to complain about empty argument lists), because () just means you are not specifying what the arguments are, at least in C, which your question is tagged as.
Declare void func1(void); as well as a in file1.h.
#include file1.h in file1.c, so the compiler checks that the definitions (in file1.c) of a and func1 are consistent with their declarations (in file1.h).
But, although you may have to do this as an exercise, try to avoid passing information in global variables: arguments are usually more reliable, as it is easier to ensure that no other part of the programme alters them. And you talk about passing information to a recursive function through a global variable: in that case you must be especially careful to pick up and save the value in func1 before a recursive call alters the value - passing an argument is so much easier and more reliable!
Ciro's solution would have worked if I am only using func1 once; however func1 is called recursively so variable a cannot be global in file1 (i.e. the variable has to live on the stack and not on the heap). Here's the solution I ended up using:
File1.c:
#include <something.h>
extern void func2_new(int b);
void func1(){
int a=0;
func2_new(a);
}
File2.c:
#include <something.h>
int a;
void func2(){
printf("%d\n",a);
}
void func2_new(int b){
a=b;
func2();
}
As many have pointed out, the only answer would be to refactor func2 completely. I welcome more input to this solution.

variable between files [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I share variables between different .c files?
If I have two source files, and one header: file1.c, file2.c, and header.h, and:
--header.h--
int i;
--file1.c--
#include <header.h>
i = 10;
int main() {
func();
return 0;
}
--file2.c--
#include <header.h>
void func() {
printf("i = %d\n", i);
return;
}
I get the warning that i defaults to an int. What could I do if I want to have i as a float for instance?
Make it
extern int i;
in the header and
int i = 10;
in file1.c.
The warning means that for the (incomplete) declaration i = 10; in file1.c, the "implicit int" rule is applied, in particular, that line is interpreted as a declaration (since an assignment cannot appear outside function scope).
You have a couple of errors in your code. The first is that you define the variable i in the header file, which means that it will be defined in all source files that include the header. Instead you should declare the variable as extern:
extern int i;
The other problem is that you can't just assign to variables in the global scope in file1.c. Instead it's there that you should define the variable:
int i = 10;
Declare it as extern in the header (this means memory for it is reserved somewhere else):
/* header.h */
extern int i;
Then define it in only one .c file, i.e. actually reserve memory for it:
/* file1.c */
int i = <initial value>;
In the header use
extern int i;
in either file1.c or file2.c have
int i = 20;
If you want float just change int to float
In 99.9% of all cases it is bad program design to share non-constant, global variables between files. There are very few cases when you actually need to do this: they are so rare that I cannot come up with any valid cases. Declarations of hardware registers perhaps.
In most of the cases, you should either use (possibly inlined) setter/getter functions ("public"), static variables at file scope ("private"), or incomplete type implementations ("private") instead.
In those few rare cases when you need to share a variable between files, do like this:
// file.h
extern int my_var;
// file.c
#include "file.h"
int my_var = something;
// main.c
#include "file.h"
use(my_var);
Never put any form of variable definition in a h-file.

How do I share a global variable between c files?

If I define a global variable in a .c file, how can I use the same variable in another .c file?
file1.c:
#include<stdio.h>
int i=10;
int main()
{
printf("%d",i);
return 0;
}
file2.c:
#include<stdio.h>
int main()
{
//some data regarding i
printf("%d",i);
return 0;
}
How can the second file file2.c use the value of i from the first file file1.c?
file 1:
int x = 50;
file 2:
extern int x;
printf("%d", x);
Use the extern keyword to declare the variable in the other .c file. E.g.:
extern int counter;
means that the actual storage is located in another file. It can be used for both variables and function prototypes.
using extern <variable type> <variable name> in a header or another C file.
In the second .c file use extern keyword with the same variable name.
Do same as you did in file1.c
In file2.c:
#include <stdio.h>
extern int i; /*This declare that i is an int variable which is defined in some other file*/
int main(void)
{
/* your code*/
If you use int i; in file2.c under main() then i will be treated as local auto variable not the same as defined in file1.c
Use extern keyword in another .c file.
If you want to use global variable i of file1.c in file2.c, then below are the points to remember:
main function shouldn't be there in file2.c
now global variable i can be shared with file2.c by two ways:
a) by declaring with extern keyword in file2.c i.e extern int i;
b) by defining the variable i in a header file and including that header file in file2.c.

Resources