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
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;
)
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.
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.
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.
How can I access a shadowed global variable in C? In C++ I can use :: for the global namespace.
If your file-scope variable is not static, then you can use a declaration that uses extern in a nested scope:
int c;
int main() {
{
int c = 0;
// now, c shadows ::c. just re-declare ::c in a
// nested scope:
{
extern int c;
c = 1;
}
// outputs 0
printf("%d\n", c);
}
// outputs 1
printf("%d\n", c);
return 0;
}
If the variable is declared with static, i don't see a way to refer to it.
There is no :: in c but you can use a getter function
#include <stdio.h>
int L=3;
inline int getL()
{
return L;
}
int main();
{
int L = 5;
printf("%d, %d", L, getL());
}
If you are talking about shadowed global var, then (on Linux) you can use dlsym() to find an address of the global variable, like this:
int myvar = 5; // global
{
int myvar = 6; // local var shadows global
int *pglob_myvar = (int *)dlsym(RTLD_NEXT, "myvar");
printf("Local: %d, global: %d\n", myvar, *pglob_myvar);
}
If you want your code to look sexy, use macro:
#define GLOBAL_ADDR(a,b) b =(typeof(b))dlsym(RTLD_NEXT, #a)
...
int *pglob_myvar;
GLOBAL_ADDR(myvar, pglob_myvar);
...
Depending on what you call shielded global variable in C, different answers are possible.
If you mean a global variable defined in another source file or a linked library, you only have to declare it again with the extern prefix:
extern int aGlobalDefinedElsewhere;
If you mean a global variable shadowed (or eclipsed, choose the terminology you prefer) by a local variable of the same name), there is no builtin way to do this in C. So you have either not to do it or to work around it. Possible solutions are:
getter/setter functions for accessing global variable (which is a good practice, in particular in multithreaded situations)
aliases to globals by way of a pointer defined before the local variable:
int noName;
{
int * aliasToNoName = &noName; /* reference to global */
int noName; /* declaration of local */
*aliasToNoName = noName; /* assign local to global */
}
what is a "shielded global variable" in pure C?
in C you have local variables, file local/global variables (static) and global variables (extern)
so file1.c:
int bla;
file2.c
extern int bla;
Yet another option is to reference the global before defining your local, or at least get a pointer to it first so you can access it after defining your local.
#include <stdio.h>
int x = 1234;
int main()
{
printf("%d\n",x); // prints global
int x = 456;
printf("%d\n",x); // prints local
}