static keyword and external variables in C - c

I have the following piece of code where I define a couple of external (global) variables after the place in code where I need to use them.
In order to do so I use the keyword extern to declare them without reserving storage for them.
int main(int argc,char *argv[])
{
extern int a;
extern double b;
/* ...use the variables somehow... */
{
int a = 10;
static double b = 2.0;
if I do so, the compiler complains that I'm defining the b variable to be static (thus with internal linkage),when before I declared it to be extern.
But if I invert the order and define it before using it and declare it inside main ( which is otpional I know...) everithing is fine.
static double b = 2.0;
int main(int argc,char *argv[])
{
extern int a;
extern double b;
/* ...use the variables somehow... */
{
int a = 10;
so what if I'd like to use an external private variable (i.e. with internal linkage) before I define it? is it forbidden and why?

The extern keyword tells the compiler that the variable we refer to is located in a different translation unit (another source file basically), while the static keyword means that the variable (in the case of global variables) is local to the current translation unit and cannot be seen in other source files, so it makes no sense to use the two keywords together.
Once you have declared b as global in the same file, it is visible in main and there is no need to declare it again, you just can use it.
If on the other hand it is declared in a different translation unit as a global variable, the extern keyword becomes necessary.

Related

why volatile can repeat declare?

#include <stdio.h>
volatile int isInit_STD;
volatile int isInit_STD;
int main() {
printf("v-%d-addr%x\n",isInit_STD,&isInit_STD);
isInit_STD = 1;
printf("v-%d-addr%x\n",isInit_STD,&isInit_STD);
return 0;
}
and the result is:
v-0-addr387fd040
v-1-addr387fd040
why volatile can repeat declare?
It turns out they are all the same, the same address.
If one of them deletes the 'volatile', that can't be compiled success.
I want to know the reason, looking forward to your reply.
The C standard says that (C17 6.7/4)
All declarations in the same scope that refer to the same object or function shall specify compatible types.
That means that as long as you use the same name, same type and same type qualifiers (volatile etc), you can declare the variable as many times as you like, and it will all refer to the same object.
And the opposite: if you use different types or qualifiers, but give the variable the same name, it is a constraint violation and the compiler must issue a diagnostic message.
Apart from what standard C allows, common sense states that we should avoid having multiple declarations of the same variable when possible. Good program design practices also state that we should avoid declaring objects at file scope, or if that's not possible, avoid using external linkage ("globals") and instead enforce interal linkage by declaring the variable static.
I want to know the reason
You can repeat a declaration of anything as many times as you want, as long as the declarations are "the same". It's not specific to volatile, just there has to be no conflict. All declarations refer to the same thing.
The following is an actual whole .c file:
// 3 declarations of function main.
int main();
int main();
int main();
// 3 declarations of struct A type.
struct A;
struct A;
struct A;
// 3 declarations of variable a
extern volatile int a;
extern volatile int a;
extern volatile int a;
// 3 declarations of variable b
int b;
int b;
int b;
// 3 declarations of variable c
volatile int c;
volatile int c;
volatile int c;
// example with conflicts:
int d;
// volatile int d; // error - conflict with above, d is not volatile
// static int d; // error - conflict with above, d is not static
extern int d; // Fine! Stuff declared at file scope is implicitly extern.

Common way of declaring/defining static, extern and inline functions in C

I know that there are multiple ways to accomplish this, i.e static could be used on both the declaration and the definition OR it could only be used on the declaration.
Is this the common way of doing so?
// `static` on both the declaration and definition.
static void f1();
static void f1(){}
// `extern` on only the declaration (shared header file).
// then define in a single source file.
extern void f2();
void f2(){}
// `inline` usually doesn't need a declaration, just define it in a shared header file.
inline int f3(){}
int main(){
return 0;
}

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!

C data segment identification

If I declare
static int a ;// globally and
static int a ; // locally in one function
So now there are two instances of a ..
I know all static variables goes into data segment but how they are differentiated in data segment which one is local and which one is global ??
You can in fact go further: you can declare
static int a;
at file scope in two or more separate files contributing to your program. Each such declaration in a different scope declares a separate variable. Thus, given
f.c:
static int a;
int f() {
static int a;
return 0;
}
main.c
static int a;
int f(void);
int main() {
return f();
}
There are three separate static variables associated with the name a in different places. It is the compiler and linker's job to arrange for the correct storage to be associated with each variable reference.

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.

Resources