I have a very mixed notion of what happens when I compile many files - mostly when it comes to the visibility of things from one file to an other. From what I read, static limits the scope of a variable or function to the file itself. extern does the opposite. From that I would expect to be able and simply read a global extern from any file. That doesn't work in practice though as seen below.
main.c:
#include <stdio.h>
int main(void){
printf("%d\n", b); // b is extern global
return 0;
}
a.c:
static int a = 40;
b.c:
extern int b = 20;
I can't even compile:
> gcc main.c a.c b.c -o test
b.c:1:12: warning: ‘b’ initialized and declared ‘extern’ [enabled by default]
extern int b = 20;
^
main.c: In function ‘main’:
main.c:4:20: error: ‘b’ undeclared (first use in this function)
printf("%d\n", b); // b is extern global
You are doing all wrong.When we writing extern int b it means an integer type variable called b has been declared.And we can do this declaration as many times as needed. (remember that declaration can be done any number of times).By externing a variable we can use the variables anywhere in the program provided we know the declaration of them and the variable is defined somewhere.
The correct way is
main.c:
#include <stdio.h>
extern int b; //declaration of b
int main(void){
printf("%d\n", b); // using b
return 0;
}
b.c:
int b = 20; //definition here
and compile as gcc main.c b.c -o test
I have omitted a.c as it was doing nothing in this example.
To understand more about externs see this site.Its having very good content http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/
A variable can be used if it is either declared or defined.
In main.c, there is no declaration of b. You can add
extern int b;
in main.c for the compiler to be able to use b. This declares to the compiler that b is defined somewhere else and it is of type int.
In b.c, you can remove the word extern. Unless qualified with static, it is extern by default.
int b = 20;
Even in b.c, you can use a declaration at the top of the file and define it at the bottom.
extern int b;
//
// ... code that uses b
//
int b = 20;
The extern line simply declares the variable. The last line defines the variable.
When you have a extern variable the compiler knows that the declaration for this variable is here and definition is somewhere else.
So you can do as shown below
some.h
extern int b; /* Declare the variable */
b.c
int b = 20; /* Define the variable */
main.c
#include<some.h>
int main()
{
printf("%d\n",b); /* Use the variable b */
return 0;
}
With this now the file main.c knows the declaration of b since it is there is some.h file.
Related
In the program
case0.c
int main()
{
int x;
x = 4;
}
x is first declared as an int, and memory is allocated for x on the following line. No problems here.
However, if I write the files (as part of a bigger program)
case1.c
extern int x;
x = 4;
I get, from gcc, warning: data definition has no type or storage class. Similarly, if I do
case2.c
extern int x = 4;
gcc also doesn't like it and gives warning: 'x' initialized and declared 'extern'
The only case that doesn't throw any warnings is
case3.c
extern int x;
int x = 4;
Why does case 1 give an error, when case 0 doesn't? Is case 3 the one and only way I should define external variables?
x is first declared as an int, and memory is allocated for x on the following line. No problems here.
No, that is not what happens. Inside a function, int x; defines x, which reserves memory for it. Then x = 4; stores a value in that memory.
extern int x;
x = 4;
extern int x; declares there to be an x but does not define it. If the program uses this x, it should define it somewhere else.
Outside a function, only declarations should appear. However, x = 4; is a statement, so it is not proper outside a function.
extern int x = 4;
This is valid C, but it is unconventional usage, so the compiler warns you. Conventionally, we write int x = 4; to define and initialize x, and we write extern int x; to declare x without defining it.
extern int x = 4; is defined by the standard; in this context, it is effectively the same as int x = 4;. But programmers generally do not use that form.
(If there is a visible prior declaration of x, such as static int x;, then extern int x = 4; does differ from int x = 4;. extern int x = 4; will refer to the x of the prior declaration, whereas int x = 4; will attempt to create a new x.)
extern int x;
int x = 4;
extern int x; declares x but does not define it.
int x = 4; defines x and initializes it.
Is case 3 the one and only way I should define external variables?
If you only need to use x in one translation unit, you can use int x = 4; by itself, without extern int x;. If you need to use x in multiple translation units, you should put extern int x; in a header file and include that header file in each source file that uses x, including the one that defines it.
"Is case 3 the one and only way I should define external variables?"
No, not if it is to be visible and usable by other source files in the project. If it is only to be used in the file in which it is created, there is no reason to give it extern duration.
The scenario requiring a variable with extern duration is when the value it stores is required to be referenced by multiple source files.
A common way (place) to create extern variables to support that scenario :
Declare variable with extern modifier in a header file.
Define the extern variable in a project file with visibility to its declaration. (eg, can be either a .h or .c . More commonly done in .c) If defined in a file other than the declaration file, file must #include the declaration file.
Use the extern variable in any source file by # including its declaration file
Example:
file.h
//anywhere in header file
extern int g_number;//declare extern variable.
//Note extern keywork required only during declaration
//Not during definition
//prototypes
void output_extern_variable( void );
void update_extern_variable( void );
...
file.c
//in file global space
#include "file.h"
int g_number = 25;//define extern variable
int main(void)
{
output_extern_variable();
update_extern_variable();
output_extern_variable();
...
file2.c
#include "file.h"
...
void output_extern_variable(void)
{
printf("Value of g_number is: %d\n", g_number);
}
void update_extern_variable( int *var )
(
g_number += 1;
)
I'd like to understand which mistake i did in the following example. There are three file: main.c, libreria_mia.c and libreria_mia.h.
// main.c
#include <stdio.h>
#include "libreria_mia.h"
int x = 5;
int main()
{
int y = quadrato();
printf("%d\n", y);
return 0;
}
// libreria_mia.h
extern int x;
int quadrato(void);
// libreria_mia.c
int quadrato(void)
{
x = x * x;
}
Error:
libreria_mia.c:5:2: error: ‘x’ undeclared (first use in this function)
Thank you for your time.
When you compile libreria_mia.c, the compiler does not automatically know about libreria_mia.h or the declarations within it. To provide a declaration for x while compiling libreria_mia.c, libreria_mia.c must include a header that declares x or have a declaration of x directly in libreria_mia.c.
Additionally, it is conventional for a header named file.h to declare things defined in file.c (not necessarily all things defined in file.c, just those intended to be used outside it). But you have x declared in libreria_mia.h but defined in main.c. Normally, one would either define x in libreria_mia.c or declare it in main.h, and usually the former as main.c is more commonly a user of all other things in the program rather than a provider.
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.
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;
}
Can anyone please tell me is there any special requirement to use either EXTERN or GLOBAL variables in a C program?
I do not see any difference in a program like below, if I change from gloabl to extern.
#include <stdio.h>
#include <stdlib.h>
int myGlobalvar = 10;
int main(int argc, char *argv[])
{
int myFunc(int);
int i;
i = 12;
myGlobalvar = 100;
printf("Value of myGlobalvar is %d , i = %d\n", myGlobalvar, i);
i = myFunc(10);
printf("Value of passed value : %d\n",i);
printf("again Value of myGlobalvar is %d , i = %d\n", myGlobalvar, i);
system("PAUSE");
return 0;
}
int myFunc(int i)
{
i = 20 + 1000;
//extern int myGlobalvar;
myGlobalvar = 20000;
// printf("Value of passed value : %d",i);
return i;
}
If uncomment extern int myGlobalvar, the value does not change.
Is there any correct difference between both?
Can anyone please correct me?
The keyword extern means "the storage for this variable is allocated elsewhere". It tells the compiler "I'm referencing myGlobalvar here, and you haven't seen it before, but that's OK; the linker will know what you are talking about." In your specific example it's not particularly useful, because the compiler does know about myGlobalvar -- it's defined earlier in the same translation unit (.c or .cc file.) You normally use extern when you want to refer to something that is not in the current translation unit, such as a variable that's defined in a library you will be linking to.
(Of course, normally that library would declare the extern variables for you, in a header file that you should include.)
From Here:
A global variable in C/C++ is a variable which can be accessed from any module in your program.
int myGlobalVariable;
This allocates storage for the data, and tells the compiler that you want to access that storage with the name 'myGlobalVariable'.
But what do you do if you want to access that variable from another module in the program? You can't use the same statement given above, because then you'll have 2 variables named 'myGlobalVariable', and that's not allowed. So, the solution is to let your other modules DECLARE the variable without DEFINING it:
extern int myGlobalVariable;
This tells the compiler "there's a variable defined in another module called myGlobalVariable, of type integer. I want you to accept my attempts to access it, but don't allocate storage for it because another module has already done that".
Since myGlobalvar has been defined before the function myFunc. Its declaration inside the function is redundant.
But if the definition was after the function, we must have the declaration.
int myFunc(int i)
{
i = 20 + 1000;
extern int myGlobalvar; // Declaration must now.
myGlobalvar = 20000;
printf("Value of passed value : %d",i);
return i;
}
int myGlobalvar = 10; // Def after the function.
In short: GLOBAL variables are declared in one file. But they can be accessed in another file only with the EXTERN word before (in this another file). In the same file, no need of EXTERN.
for example:
my_file.cpp
int global_var = 3;
int main(){
}
You can access the global variable in the same file. No need to use EXTERN:
my_file.cpp
int global_var = 3;
int main(){
++global_var;
std::cout << global_var; // Displays '4'
}
Global variable, by definition, can also be accessed by all the other files.
BUT, in this case, you need to access the global variable using EXTERN.
So, with my_file.cpp declaring the global_var, in other_file.cpp if you try this:
other_file.cpp
int main(){
++global_var; // ERROR!!! Compiler is complaining of a 'non-declared' variable
std::cout << global_var;
}
Instead, do:
int main(){
extern int global_var;//Note: 'int global_var' without 'extern' would
// simply create a separate different variable
++global_var; // and '++global_var' wouldn't work since it'll
// complain that the variable was not initiazed.
std::cout << global_var; // WORKING: it shows '4'
}
myGlobalVar as you've defined it is a global variable, visible from all the places in your program. There's no need declaring it extern in the same .c file . That is useful for other .c files to let the compiler know this variable is going to be used.