defining an extern variable in a fucntion [duplicate] - c

This question already has answers here:
Can local and register variables be declared extern?
(5 answers)
Closed 3 years ago.
Assume the following:
test1.h
extern int a;
void init();
test1.c
#include <stdio.h>
#include "test1.h"
int main()
{
init();
printf("%d\n", a);
return 0;
}
test2.c
#include "test1.h"
void init()
{
int a = 1;
}
Above will give me a linker error saying a isn't defined, but it is defined under init().
However, if I change test2.c like this then it will work:
int a = 1;
void init()
{
//
}
Does extern have to be defined globally only?

The internal or external linkage may have only variables that have a file scope.
In your first example
void init()
{
int a = 1;
}
the variable a has a block scope and hence does not have a linkage.
In the header
extern int a
there is declared a variable with external linkage that has the file scope. But it was not defined. So the linker issues an error because it can not find the variable definition.
You may declare a block scope variable with the extern specifier. But it will not be a variable definition. The declaration will refer to a variable with a linkage declared in a file scope.
For example consider the following demonstrative program
#include <stdio.h>
int x = 10;
void f( void )
{
extern int x;
printf( "x = %d\n", x );
}
int main(void)
{
f();
x = 20;
f();
return 0;
}
Its output is
x = 10
x = 20
That is there is defined the file scope variable x with the external linkage. And within the outer block scope of the function f the declaration of the variable x refers to the variable x in the file scope. It does not define a new object.

Related

Is variable declaration necessary in C?

See the comments to see what is being referred as declaration.
If the whole variable declaration part was missing, what would be the problem?
Appears that variable definition and initialization either simultaneously or separately like in the example would suffice.
#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;
}
If the declaration was missing then it would create no problem in main function since the locally defined variables i.e. a,b,c,f will be used in the functionality of main till its scope ends.
The declaration merely tells that the definition lies elsewhere (in some other .c file) or the definition lies after the function main in the same .c file.
There will be no problem here if the mentioned declaration is missing.
// Variable declaration:
extern int a, b;
extern int c;
extern float f;
This tells the compiler that these variables are defined somewhere else(in another file).
/* variable definition: */
int a, b;
int c;
float f;
This is where you define variables but they are not the same as the external variables you declared since they are in the inner scope of the main function.
The scope is the place where variables live. extern keyword notes that the scope is global.
You can define variables with the same name in an inner scope and access only them as you did in the main function but it's not a good practice.
void foo()
{
int a = 5;
printf("%d\n", a); // 5
// Creating an inner scope
{
int a = 20;
printf("%d\n", a); // 20
}
printf("%d\n", a); // 5
}
The correct way to use the extern keyword with variables is like this.
//h1.h
extern int global_var; // Declaration of the variable
//c1.c
#include h1.h
int global_var = 0; // Definition of the global var. Memory is allocated here.
//main.c
#include h1.h
int main()
{
printf("global var value is %d\n", global_var); // use of the var defined and
// initialized in c1.c
return 0;
}
This program will print 0 since the variable is defined and initialized in c1.c.
Extern extends the visibility of the C variables and C functions. so that lets the compiler know that there is another place that those vars are declared and memory was allocated for them elsewhere.
for example in another c file.
if you compile a c file containing a global var for example:
int c = 5;
and you create a function on you c file that uses this c var, for example:
int someFunc(void){
return c;}
if you run someFunc in your main and print its return value, you will get 5. but you must compile both c files together.
in your program, you only use the locally allocated var declared in your main function.
When it comes to simple variables, there is really no difference between the declaration and definition. There is a difference when it comes to structs and functions. Here is an example:
// Declarations
struct myStruct;
int foo();
int main()
{
...
}
// Definitions
struct myStruct {
int a, b;
};
int foo() {
return 42;
}
In your case, you are hiding the previous declarations so that they are not accessible before the end of the scope. This is commonly called shadowing. It's basically the same thing as this:
int main()
{
int i=0;
printf("i: %d\n", i);
{
int i=42; // Now the previous i is inaccessible within this scope
printf("i: %d\n", i);
}
// And now it is accessible again
printf("i: %d\n", i);
}

Can a static variable be declared extern in C?

So, let's say, I have:
file1.c
int i;
static int j;
int main ()
{
for ( int k = 0; k < 10; k++ )
{
int foo = k;
}
}
file2.c
{
// the following statements are before main.
extern int i; // this is acceptable, I know since i acts as a global variable in the other file
extern int j; // Will this be valid?
extern int foo; // Will this be valid as well?
}
I therefore, have a doubt that the statements marked with a question mark, will they be valid?
No! static globals have file scope (internal linkage), so you can't use them as they have external linkage... This does not means that you cannot have a variable of the same name with external linkage but it cannot be that one that is static.
Correct for i.
Incorrect for j, at least it cannot be the one defined in file1.c.
Incorrect for foo, at least for the local variable used in file2.c which does not have external linkage (no linkage at all). A local variable only exists when the block where it is declared is activated, so having access to it outside is a non-sense.
extern int j; is not a valid -> static variables are with in the file scope
extern int foo; is not valid -> foo is a local variable whose scope is with in the 'for' loop

Global value is not acessable in another file? [duplicate]

This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 8 years ago.
Global value is not accessible in another file?Mycode is below please help me to fix
flie1.c
#include<stdio.h>
extern int i=9;
int main()
{
printf("i m in main\n");
}
file2.c
printf("%d\n",i);
i am compiling both file at once as cc file1.c file2.c
Change it like this, and it will work:
file1.c
#include <stdio.h>
int i = 9; // define the variable
void print(); // declare print: say there is a function called `print` with no arguments and no return type (because the function is DEFINED in file2.c)
int main() {
printf("im in main");
print();
return 0;
}
file2.c
extern int i; // declare "i": say there is a variable called `i` with type of `int` (because the variable is DEFINED in file1.c)
void print() {
printf("%d\n", i);
}
When you have an extern variable, it should also have its 'original' declaration (without using extern). extern simply says ' this variable is defined elsewhere', so you need to define the variable somewhere.
Simply add:
int i=9;
to file2.c (in the top of the file, the 'globals' area')
and you can change your extern declaration to:
extern int i;
(without the assignment of the value 9) in file1.c

how to use extern in C?

I have this code:
#include <stdio.h>
extern int x;
void a() {
int x = 100;
printf("%d ",x );
x += 5;
}
void b() {
static int x = -10;
printf("%d ", x);
x += 5;
}
void c(){
printf("%d ", x);
x += 2;
}
int main() {
int x = 10;
a();
b();
c();
a();
b();
c();
printf("%d ", x);
getchar();
return 0;
}
int x = 0;
I was sure that the fact that extern in declared here, I will have a compilation error - but everything passed.
also , what is the meaning of extern when it's inside the C file itself? shouldn't it be in another file?
Is there a way to declare this variable in order for this not to compile?
The extern keyword declares a variable, and tells the compiler there is a definition for it elsewhere. In the case of the posted code, the definition of x occurs after main(). If you remove the int x = 0; after main() the code will not build (it will compile but will fail to link due to undefined symbol x).
extern is commonly used to declare variables (or functions) in header files and have the definition in a separate source (.c) file to make the same variable available to multiple translation units (and avoid multiple definition errors):
/* my.h */
#ifndef MY_HEADER
#define MY_HEADER
extern int x;
#endif
/* my.c */
#include "my.h"
int x = 0;
Note that the declaration of x in functions a(), b() and main() hide the global variable x.
You have a declaration for an identifier at file scope, so if no other declaration for the identifier would've been existing at file scope, the identifier would have had and external linkage. But, you've defined the identifier at file scope at the last line, in the pasted code.
So,extern int x;
refers to the globally defined: int x = 0; at the bottom of your file. :)
If you run this code you should get x's value as 2 and subsequently 4 because the externed x variable refers to the int x=0 after the main().
Extern is used for declaration a variable in a compilation unit, this variable was defined in other compilation unit.
What is the difference between a definition and a declaration?
For functions it is optional.
Read: http://en.wikipedia.org/wiki/External_variable
In your piece of code, each of the three function uses another 'i'. Only c() uses the global x.

C Undefined reference

I got some problem with the following codes particularly in header.c where i can't access the extern int x variable in header.h... Why? Does extern variable in .h not global? How can i use this on other files?
===header.h===
#ifndef HDR_H
#define HDR_H
extern int x;
void function();
#endif
===header.c===
#include <stdio.h>
#include "header.h"
void function()
{
printf("%d", x); //****undefined reference to x, why?****
}
===sample.c===
int main()
{
int x = 1;
function();
printf("\n%d", x);
return 0;
}
The declaration
extern int x;
tells the compiler that in some source file there will be a global variable named x. However, in the main function you declare a local variable x. Move that declaration outside of main to make it global.
The extern keyword say the variable exists but does not create it. The compiler expects that another module will have a global variable with that name, and the linker will do the right thing to join them up.
You need to change sample.c like this:
/* x is a global exported from sample.c */
int x = 1;
int main()
{
function();
printf("\n%d", x);
return 0;
}
extern declares a variable, but does not define it. It basically tells the compiler there is a definition for x somewhere else. To fix add the following to header.c (or some other .c file but only one .c file):
int x;
Note that in main() the local variable x will hide the global variable x.
Indeed extern int x; means x will be defined in another place/translation unit.
The compiler expects to find a definition of x in the global scope somewherelse.
I would reorganise/modify your code like this and get rid of header.c
===sample.h===
#ifndef SAMPLE_H
#define SAMPLE_H
extern int x;
void function();
#endif
===sample.c===
#include <stdio.h>
#include "sample.h"
int x;
void function()
{
printf("%d", x);
}
int main()
{
x = 1;
function();
printf("\n%d", x);
return 0;
}

Resources