a global variable may one to two different storage classes in C, to my best knowledge, and the declaration may be given with two different keywords, correspodingly
extern int foo; //default
static int bar;
Static variables are only visible within the module of declaration, and cannot be exported. In case of extern declaration, the variable is in the common namespace of all modules linked, unless shadowed by static variable.
Whereas static variables have to be defined in their module, an extern variable may be defined somewhere else. It has to be defined if ever used.
My compiler (GCC) accepts
static int bar = 5;
but casts a complain at
extern int foo = 4;
It seems to be expected that extern variables are never defined with the keyword 'extern'. This leads to the following question:
What kind of storage class does the Object 'foo' in the example above have in the module where it is defined?
IIRC, extern is more of a hint to the compiler that it does not have to allocate storage for the value. The linker is expected to find the value in another compilation unit. Usually extern is used in header files to indicate that the someone has defined storage associated with the name. The definition of the value does not include the extern keyword since the compiler has to allocate storage for the value in the compilation unit that includes the definition.
See extern storage class specifier for more details.
The extern variable will be defined with a global scope (exported) in the unit where it is defined:
int baz = 5;
The default storage class is auto.
Actually you missed two storage classes: auto and register
Register doesn't matter here but the default storage class is auto.
Auto reserves space for a variable somewhere in the memory (which is usually what you want when you declare a variable). It should be noted that for 'auto variables' new space will be allocated every time the scope of the variable is entered. (i.e. calling the function func() from within func() when func() declares an 'auto' variable will result in two different variables and each call to func() will only know about its own variable.
From this follows that auto variables declared at the global scope will be unique (since the scope is enterd only once).
Static variables however are always unique. Unique in the sense that space will only be allocated once. This is useful when func() calls func() and you want both function calls to operate on the same variable.
Extern variables are simply references to unique variables.
You use these when you want to access a global variable declared in a different file.
Given the files 1.c and 2.c it does not suffice to declare "int global;" in both files because space would be allocated twice and the name clash would result in a linking error.
Hence what you do is in one file to reserve space (using "int global;") and in the other file tell the linker to look for a variable of the name "global" in another file by writing "extern int global;".
Related
I have read about global and local variables and static keyword, but i dont know which is the difference between something like this:
int x; //Global variable
int main(){
//Code...
}
And this:
static int x; //Static Global variable
int main(){
//Code...
}
I know some properties of the static keyword, and i know why is useful for local variables, but i dont know which is the use for global variables
I have read that using static for global variables is used for accesing the variable only in the C file it is declared/defined, but, i mean, if we dont use extern we just cant access that global variable in other c files anyway
I think that a "static global" variable is used to prevent the use of the extern keyword in order to prevent the use of that variable in multiple C files, is that correct?
Thanks in advance!
"Global" is not a formal term, but it generally means "variable that can be accessed anywhere". Therefore global.
To dive into some formal terms:
The formal and correct term for a variable declared outside a function is declared at file scope.
What formally defines how a variable may be accessed in C is referred to as linkage.
A variable declared at file scope generally has external linkage and can be referred to from elsewhere with extern.
So the correct term to use for your first example is "file scope variable with external linkage".
Whenever we add the storage class specifier static to a declaration, we force the variable or function to instead get internal linkage. This means that it is only accessible from within the translation unit (the .c file and all .h files it includes) where it was declared.
It is the opposite of global, so saying "static global" doesn't make any sense. You cannot refer to such a variable with extern. Instead the correct term is "file scope variable with internal linkage".
The main purpose of static is indeed private encapsulation, since the internal linkage guarantees that the variable or function cannot be accessed by other .c files.
But static also at the same time gives static storage duration to a variable, meaning it is guaranteed to persist throughout the execution of the program and that it has some initialization rules guaranteed. Now as it happens, variables at file scope always gets static storage duration, static or not, so it isn't very relevant to your example. But as you earlier discovered, static storage duration does make a big difference for local variables, since their value will then be preserved throughout multiple function calls.
More details here: What does the static keyword do in C?
Yes, it is correct.
A global static variable can only be accessed in the file where it is created (file scope).
From https://www.quora.com/What-are-the-types-of-linkages-in-C-programming
External linkage, means that the variable could be defined somewhere
else outside the file you are working on, which means you can define
it inside any other translation unit rather your current one (you
will have to use the keyword extern when defining it in the other
source code).
Internal linkage, means that the variable must be defined in your
translation unit scope, which means it should either be defined in any
of the included libraries, or in the same file scope.
None linkage, points to the default functions and braces scopes, such
as defining an auto variable inside a function, this will make the
variable only accessable within that function's scope.
Note that:
Any global object is externally linked by default, you can disable that by using the keyword static.
Any constant global object is internally linked by default, you can
disable that by using the keyword extern.
Suppose a global variable is defined in file1 and I want to use it in file2.
In file1, shall the global variable be defined with keyword
extern?
The quote above seem to contradict itself:
"you will have to use the keyword extern when defining it in the other source code" seems to say it should.
"Any global object is externally linked by default" seems to say that it doesn't need to.
In file2, shall I declare global variable with keyword extern?
tldr: You should declare the variable, with extern, in a header file which is included by both file1 and file2. You should then define the variable in file1 only. To define the variable, you declare it without extern (and also without static).
You sound like you have gotten the extern keyword and the standardese term "external linkage" mixed up.
A variable with "external linkage" is accessible from any function in the program, as long as a declaration of the variable is visible to that function. In contrast, a variable with "internal linkage" is accessible from, at most, one "translation unit" (a single source file and all the files it includes), and a variable with "no linkage" is only visible within a single function. (I don't remember off the top of my head whether a static variable declared within a function is considered to have internal linkage or no linkage.)
The extern keyword, applied to a variable declaration, has two effects. First, it guarantees that that variable will be given external linkage, even if the declaration is inside a function (don't do that). Second, and much more importantly, it makes the declaration not be a definition. What that means is, if you have these two files
/* file1.c */
extern int foo;
/* file2.c */
extern int foo;
int main(void) { return foo; }
their combination is not a valid program. You will get an error from the linker, probably reading something like "undefined reference to foo".
To make this a valid program, you must remove the extern from one of the two declarations of foo. That declaration then becomes a definition, and the program will link. (Also, that declaration can then be given an initializer, if you want it to have a value other than 0 at startup.)
If you remove the extern from both of the definitions of foo, the result is, IIRC, implementation-defined. Some C compilers will merge them into a single global variable, and others will issue a link-time error. Sometimes the behavior depends on whether or not the variables have initializers.
It is OK to write
/* file1.c */
extern int foo;
/* file2.c */
extern int foo;
int foo;
This allows you to put the extern declaration in a header file that both .c files include, which reduces the risk of the declarations coming to have inconsistent types (if this happens, the program will exhibit undefined behavior).
c11 draft, 6.2.2, 4th section, states:
For an identifier declared with the storage-class specifier extern in a scope in which a
prior declaration of that identifier is visible,31) if the prior declaration specifies internal or
external linkage, the linkage of the identifier at the later declaration is the same as the
linkage specified at the prior declaration. If no prior declaration is visible, or if the prior
declaration specifies no linkage, then the identifier has external linkage.
i don't think there will be any difference with or without extern keyword. some experiment also indicates that:
following 2 compiled:
extern int a;
extern int a;
int a = 20;
and
extern int a;
int a;
int a = 20;
but not this one:
extern int a;
int a = 10;
int a = 20;
however, i have some impression that once i read about the different behavior when dynamic linkage get involved in windows. I cannot find it though. it would be nice if anyone can confirm.
The text you quoted has a lot of errors. I would recommend not relying on information from that site.
(you will have to use the keyword extern when defining it in the other source code).
Not true, as file-scope definitions have external linkage unless the static keyword is used (or no specifier is used and they are re-declaring something already declared with the static keyword).
It is possible to include a redundant extern in the definition, however there must also be an initializer (otherwise it would be a declaration and not a definition).
Internal linkage, means that the variable must be defined in your translation unit scope, which means it should either be defined in any of the included libraries, or in the same file scope.
Presumably this means "included headers", not "included libraries".
Any constant global object is internally linked by default, you can disable that by using the keyword extern.
This is wrong, "global objects" have external linkage unless declared with static. The author might be mixing up C with C++ (in the latter, const global objects have internal linkage unless otherwise specified).
Suppose a global variable is defined in file1 and I want to use it in file2.
// file1.h (or any other header)
extern object_t obj;
// file1.c
#include "file1.h"
object_t obj; // or: extern object_t obj = { 1, 2, 3 };
// file2.c
#include "file1.h"
For our assignment we have to code a program in C, but it says not to use external variables in the program. Does this mean variables in other files brought into the main code, or am I unable to use variables in the same file if they're not in the same function? (ie: could I pass a value into a function as an argument and have it return a value that may have to do with a variable in that function and set the return value equal to something, or is that using external variables?)
I've Googled around but it's not exactly clear, and I want to make sure, as this is rather important.
Just to be sure, I'd make all my variables part of a function, and either pass them as parameters or return them from the functions.
There are at least two interpretations of external variables.
First off, we have the extern keyword, which basically symbolizes what you would call a global variable. It's a variable declared in multiple translation unit, but it only exists in one place in memory. It is initialized in a single file and all subsequent changes affect every scope the variable is used in:
//globals.cpp
int x = 1337;
//main.cpp
extern int x;
int main()
{
//x is 1337 here
return 0;
}
The second meaning could be a variable that is declared and defined in class scope, but not used as extern. However, you could consider it external to the methods.
//main.cpp
int x = 1337; //is this external?
//could be, remove it just to be safe
int main()
{
return 0;
}
Let's go with all the possible cases, because from your question I'm not too sure either:
There is extern as a keyword. In order to understand this, you need to understand compilation units. Basically, each file is a compilation unit - so each .c is compiled to a .o with the headers substituted in place. In each compilation unit, you forward declare symbols you expect to use - functions belonging to other compilation units, for example.
Now, if you declare a global variable in one .c file, it is global wrt that file, but does not exist as a symbol in any other file at all - the compiler will error because it doesn't know where that variable was declared.
(Of course, if you declare the variable in a header - it will exist in all of the objects the header is included in, and then the linker will sulk, because when it links all the objects up some of the symbols will have the same name).
To get around this, it is possible to define a variable with extern int x;, for example. This tells the compiler a) int x should be available to this compilation unit, b) int x is not in this compilation unit and c) the linker should check it exists somewhere in all the units you've put together to form a library or program.
Conceptually, you're doing this all the time with forward-declarations of functions. There's just no way to forward declare a variable. In fact, you can do this with functions too and not bother r.e shared headers, although this is not really a good idea.
The other case is that "external variables" mean something external to a certain scope or module you have. I would check your assignment very carefully and if in doubt ask - whoever set it should be able to explain to you exactly what they mean.
An external variable is a variable with external linkage.
A variable with external linkage is a variable defined at file scope without the static keyword.
int bla = 0; // external variable
static int blop = 1; // non-external variable
int main(void)
{
return bla
}
Note that a variable declared with the extern keyword doesn't necessarily have external linkage. Like const does not mean constant in C, extern does not mean external.
People often use the word external to say that a variable is actually declared in the current translation unit but is defined in another translation unit.
I am new to Linux. I came across this piece of code to print environmental variables. It is kind of confusing me. How can this code print the environmental variables?
#include <stdio.h>
extern char **environ;
int main()
{
char **var;
for(var=environ; *var!=NULL;++var)
printf("%s\n",*var);
return 0;
}
what is extern here?
If you don't know what extern means, please find a book to learn C from. It simply means 'defined somewhere else, but used here'.
The environ global variable is unique amongst POSIX global variables in that it is not declared in any header. It is like the argv array to the program, an array of character pointers each of which points at an environment variable in the name=value format. The list is terminated by a null pointer, just like argv is. There is no count for the environment, though.
for (var = environ; *var != NULL; ++var)
printf("%s\n", *var);
So, on the first iteration, var points at the first environment variable; then it is incremented to the next, until the value *var (a char *) is NULL, indicating the end of the list.
That loop could also be written as:
char **var = environ;
while (*var != 0)
puts(*var++);
From wikipedia http://en.wikipedia.org/wiki/External_variable:
Definition, declaration and the extern keyword
To understand how external variables relate to the extern keyword, it is necessary to know the difference between defining and declaring a variable. When a variable is defined, the compiler allocates memory for that variable and possibly also initializes its contents to some value. When a variable is declared, the compiler requires that the variable be defined elsewhere. The declaration informs the compiler that a variable by that name and type exists, but the compiler need not allocate memory for it since it is allocated elsewhere.
The extern keyword means "declare without defining". In other words, it is a way to explicitly declare a variable, or to force a declaration without a definition. It is also possible to explicitly define a variable, i.e. to force a definition. It is done by assigning an initialization value to a variable. If neither the extern keyword nor an initialization value are present, the statement can be either a declaration or a definition. It is up to the compiler to analyse the modules of the program and decide.
A variable must be defined once in one of the modules of the program. If there is no definition or more than one, an error is produced, possibly in the linking stage. A variable may be declared many times, as long as the declarations are consistent with each other and with the definition (something which header files facilitate greatly). It may be declared in many modules, including the module where it was defined, and even many times in the same module. But it is usually pointless to declare it more than once in a module.
An external variable may also be declared inside a function. In this case the extern keyword must be used, otherwise the compiler will consider it a definition of a local variable, which has a different scope, lifetime and initial value. This declaration will only be visible inside the function instead of throughout the function's module.
The extern keyword applied to a function prototype does absolutely nothing (the extern keyword applied to a function definition is, of course, non-sensical). A function prototype is always a declaration and never a definition. Also, in ANSI C, a function is always external, but some compiler extensions and newer C standards allow a function to be defined inside a function.
An external variable must be defined, exactly once, outside of any
function; this sets aside storage for it. The variable must also be
declared in each function that wants to access it; this states the
type of the variable. The declaration may be an explicit extern
statement or may be implicit from context. ... You should note that we
are using the words definition and declaration carefully when we refer
to external variables in this section. Definition refers to the place
where the variable is created or assigned storage; declaration refers
to places where the nature of the variable is stated but no storage is
allocated.
—The C Programming Language
Scope, lifetime and the static keyword
An external variable can be accessed by all the functions in all the modules of a program. It is a global variable. For a function to be able to use the variable, a declaration or the definition of the external variable must lie before the function definition in the source code. Or there must be a declaration of the variable, with the keyword extern, inside the function.
The static keyword (static and extern are mutually exclusive), applied to the definition of an external variable, changes this a bit: the variable can only be accessed by the functions in the same module where it was defined. But it is possible for a function in the same module to pass a reference (pointer) of the variable to another function in another module. In this case, even though the function is in another module, it can read and modify the contents of the variable—it just cannot refer to it by name.
It is also possible to use the static keyword on the definition of a local variable. Without the static keyword, the variable is automatically allocated when the function is called and released when the function exits (thus the name "automatic variable"). Its value is not retained between function calls. With the static keyword, the variable is allocated when the program starts and released when the program ends. Its value is not lost between function calls. The variable is still local, since it can only be accessed by name inside the function that defined it. But a reference (pointer) to it can be passed to another function, allowing it to read and modify the contents of the variable (again without referring to it by name).
External variables are allocated and initialized when the program starts, and the memory is only released when the program ends. Their lifetime is the same as the program's.
If the initialization is not done explicitly, external (static or not) and local static variables are initialized to zero. Local automatic variables are uninitialized, i.e. contain "trash" values.
The static keyword applied to a function definition prevents the function from being called by name from outside its module (it remains possible to pass a function pointer out of the module and use that to invoke the function).
Example (C programming language)
File 1:
int GlobalVariable; // implicit definition
void SomeFunction(); // function prototype (declaration)
int main() {
GlobalVariable = 1;
SomeFunction();
return 0;
}
File 2:
extern int GlobalVariable; // explicit declaration
void SomeFunction() { // function header (definition)
++GlobalVariable;
}
In this example, the variable GlobalVariable is defined in File 1. In order to utilize the same variable in File 2, it must be declared. Regardless of the number of files, a global variable is only defined once, however, it must be declared in any file outside of the one containing the definition.
If the program is in several source files, and a variable is defined in file1 and used in file2 and file3, then extern declarations are needed in file2 and file3 to connect the occurrences of the variable. The usual practice is to collect extern declarations of variables and functions in a separate file, historically called a header, that is included by #include at the front of each source file. The suffix .h is conventional for header names.
Extern defines a variable or a function that can be used from other files... I highly advise reading some of the many articles available on the Internet on C programming: https://www.google.ca/search?client=opera&rls=en&q=learn+c&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest
extern char **environ;
the variable environ comes from your library which you will link.
That variable saved the system environment variables of your current
linux system. That's why you can do so.
Why does extern int n not compile when n is declared (in a different file) static int n, but works when declared int n? (Both of these declarations were at file scope.)
Basically, why is int n in file scope not the same as static int n in the same scope? Is it only in relation to extern? If so, what about extern am I missing?
The whole and entire purpose of static is to declare that a variable is private to the source file that it is declared in. Thus, it is doing precisely its job in preventing a connection from an extern.
Keep in mind that there are four flavors of file-scope variable definition:
int blah = 0; — blah is defined in this file and accessible from other files. Definitions in other files are duplicates and will lead to errors.
extern int blah; — blah must be defined elsewhere and is referenced from this file.
int blah; — This is the moral equivalent of FORTRAN COMMON. You can have any number of these in files, and they are all resolved by the linker to one shared int. (*)
static int blah; (optionally with an initializer) — This is static. It is completely private to this file. It is not visible to externs in other files, and you can have many different files that all declare static TYPE blah;, and they are all different.
For the purists in the audience: 'file' = compilation unit.
Note that static inside functions (not at file scope) are even more tightly scoped: if two functions declare static int bleh = 0; even in the same file, they are unrelated.
(*): for those of you not familiar: in the usual pattern, one compilation unit has to define a global variable, and others can reference it. It 'lives' in that compilation unit. In case (3), above, no file (or all the files) defines it. If two files say int blah = 0;, the linker will complain of multiple definitions. If two files say int blah; the linker cheerfully creates a single global int and causes all the code to refer to it.
In standard C, there are two scopes for variables declared outside of a function. A static variable is only visible inside the compilation unit (i.e., file) that declared it, and non-static variables are visible across the whole program. An extern declaration says that the variable's location isn't known yet, but will be sorted out by the linker; it's compatible with non-static variables, but extern static is just crazy talk!
Of course, in practice there are other visibilities these days. In particular, there are now scoping levels between that of a single source file and a whole program; the level of a single shared library is a useful one (settable through mechanisms like GCC function attributes). But that's just a variation on the theme of non-static variables; static keeps the same interpretation it had before.
According to MSDN documentation:
When modifying a variable, the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified. When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage (its name is not visible from outside the file in which it is declared).
Static (C++) on MSDN: Archived in January 2015; see also the latest documentation: static § Storage classes (C++) | Microsoft Docs
iv.c:2:1: error: multiple storage classes in declaration specifiers
extern static int i;
^
That is what we get on attempting to extern a static variable. Declaring extern static int i; - is analogous to the declaration float int i;
You can't have float and int appear in the same declaration right? Similarly, you can't have extern and static in the same declaration.