I was looking for a function to do some audio effect, and I found one written in C.
Inside this function, some variables are declared as Static. I am confused, I thought Static means these variables are not visibles to other files. But since they are declared inside inside a function, they are already not visible to other files.
What am I missing ?
static inside a function means that it will hold its value the next time the function is called.
For example,
int foo() {
static int i = 0;
printf("%d\n", i);
i++;
}
int main() {
foo(); // Prints 0
foo(); // Prints 1
}
Related
I learned some C and came across an explanation for static variables.
They showed this code:
#include<stdio.h>
int fun()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("%d ", fun());
printf("%d ", fun());
return 0;
}
I can't understand why calling the function twice is fine, because the line
static int count = 0;
actually runs twice...
I can't understand how is that possible...
Can you actually declare it twice or does the compiler just ignore it the second time?
This (statics/globals) is where an initializing definition is really different from an uninitialized definition followed by an assignment.
Historically, the former even used to have different syntax (int count /*no '=' here*/ 0;).
When you do:
int fun() {
static int count = 0;
//...
}
then except for the different scopes (but not lifetimes) of count, it's equivalent to:
static int count = 0; //wider scope, same lifetime
int fun() {
//...
}
In both cases, the static variable becomes initialized at load time, typically en-masse with other statics and globals in the executable.
static variables are initialized on program startup, not every time the function is called.
... because the line static int count = 0; actually runs twice.
No. Just once, right before main() is called.
I read that : static variable is initialised only once (unlike auto variable) and further definition of static variable would be bypassed during runtime. from the link.
then why I am getting error that "i was not declare " in the code given below.
I wrote program such that the static variable "i" initialized only first time when c is equal to 0 after that c increases.
I just want to know how the static variable really works and that's why i am declare static variable only once. My question is if static variable only declare once in each function call then why my code is not running and if it is necessary to declare it in each calling then why it does not initialise in each function call.
#include<stdio.h>
int c=0;
int test()
{
if(c==0)
{
static int i=0;
}
c++;
i++;
if(i==5)
printf("%d\n",i);
else
test();
}
int main()
{
test();
return 0;
}
You define the variable inside the local scope of if. It has no scope outside. static only deals with the extent (aka lifetime).
Use curly braces and indention. Then you will see your mistake.
Because the scope of i is just the if block in following code:
if(c==0)
static int i=0;
same as
if(c==0)
{
static int i=0;
}
i is not available outside the if block
If you put static variable inside of block or function then that variable will not longer available out of scope because without a curly brace {} only first statement after the if is executed. So it cannot be used anywhere else and compiler gives an error.
To fix your compilation error, declare I outside the condition. And set it to zero inside the condition -
static int i;
if ( c == 0 )
i = 0;
This will make the error go away.
But what you are trying to achieve doesn't require you to have a global variable c.
You can simply do
static int i = 0;
i++;
The first time it will be set to zero, hence forth it will not be initialized.
Its because , scope of variable 'i' is only inside (if) . So when you are incrementing 'i' , Compiler will throw error.
Adding the braces that others have mentioned will not fix the problem. The real solution is to just remove the if (c == 0) line completely. The static declaration of i should be the first line of the function.
What you want is this:
int test()
{
static int i=1;
if(i==5)
printf("%d\n",i);
else
test();
}
Automatic Storage used in a function does not re-initialize the i variable declared using the auto keyword.
Practice.c : main() and func() are in the Practice.c
#include <stdio.h>
main()
{
func();
func();
func();
}
func()
{
auto int i=1;
printf(" i = %d",i);
i=i+1;
}
After compilation when I execute Practice.exe the output is as follows :
i = 1
i = 1
i = 1
Every time main() calls func() i is re-initialized to 1. This is correct as scope of i is within the func() block, and when the control comes out of this block the value of i is lost. So, when I will be calling this func() function for the second time the value of i will be re-initialized to 1.
Check the following New.c Program.
New.c : contains both main() & func()
#include <stdio.h>
main()
{
func();
func();
func();
func();
func();
func();
func();
func();
}
func()
{
auto int i;
printf(" i = %d",i);
i=i+1;
}
Just to be sure, I called the function func() 8 times.
But in New.c, i is not initialized. When I executed this program after compilation, the output of it is as follows :
i = 4201582
i = 4201583
i = 4201584
i = 4201585
i = 4201586
i = 4201587
i = 4201588
i = 4201589
The output shows increment on every call. What is the exact reason behind this ?
The output shows increment on every call. What is the exact reason
behind this ?
Variables with automatic storage allocation are not initialized by default and it is undefined behaviour to access an uninitialized variable. This means the behaviour of your second program cannot be reasoned out.
Also, note that the default stororage class of variables in function scope is automatic. Therefore, you don't need the auto keyword to qualify the definition of i.
// in function scope
auto int i;
// equivalent to
int i;
Also, it's wrong to say
So, when I will be calling this func() function for the second time
the value of i will be re-initialized to 1.
The variable i is not re-initialized. It goes out of scope once the function containing it returns. When the function is called again, it's again allocated on the stack. This does not mean that it is allocated on the same memory address.
Also, you need to take care of the return type and parameter list of the functions. The implicit return type is int and empty parameter list means no information is available about the number and type of arguments which means the function takes a fixed but unknown number of arguments of unknown type. You should always explicitly mention void in the parameter list to mean that the function takes no argument.
#include <stdio.h>
// prototype of the function func
void func(void);
// main should have one of the below signatures -
// int main(void); or
// int main(int argc, char *argv[]);
int main(void)
{
func();
func();
func();
}
// explicitly mention void in the
// parameter list to mean the function
// takes no argument
void func(void)
{
// using auto keyword is redundant because
// local variables have automatic storage allocation
int i = 1;
printf("i = %d", i);
i = i + 1;
}
In the second case, you make use of i without ever having initialized it.
The value is therefore undefined by the language. The fact that you see a pattern of the value incrementing is an artifact of the particular compiler you are using.
In the first iteration, you have a random-seeming value that happens to be at the memory location that i represents. Your function increments the value at that memory location, then that memory location happens to be used for subsequent calls.
I am learning storage classes in C.I have a simple code
enter code here
int f1()
{
static int i=0;
i++;
printf("%d",i);
}
int f2()
{
printf("%d",i);
}
int main()
{
f1();f2();f1();f2();
}
Compiler gives error as 'i' is undeclared in f2().
As I thought,memory static variables are allocated in data section of program memory.So any function in that file should be able to access it.
How does compiler knows that variable locally declared in function is bounded to that function only?How compiler evaluates that?
Although the lifetime of static variable isn't tied to the scope where it is defined (unlike variables with automatic storage duration):
{
static int i=0;
i++;
...
{
i++; // <-- still well defined, even in nested scope
}
}
i++; // <-- undefined
it is accessible only within this scope. The compiler just checks whether the symbol i has been defined before and it sees, that i has not been defined within that scope (the static int i=0; defines a variable that is accessible locally ~ compiler doesn't care about its lifetime).
In case you need it to be accessible out of its scope, you'll have to pass it out of it by reference (its address) or make it global:
static int i = 0;
...
{
i++;
}
...
i++; // <-- accessing global variable
static variables are indeed stored in the data section but are only in the scope of the function they are declared in.
You should do the following
static int i=0;
int f1()
{
i++;
printf("%d",i);
}
int f2()
{
printf("%d",i);
}
now the variable i can be accessed by both functions.
Always remember that the Scope is compile time not run-time. C has a flat memory structure. This means you can access anything from anywhere. You can make a pointer of i and can access it. But, C says undefined behaviour when the scope of the variable is over. This is a compiler restriction completely. You can also see the link - Is scope in C related only to compile time, as we know we can access any memory at run time? for more details. Also, this could be helpful A static variable and a global variable both reside in data segment. Still, static variable has scope limited. Why?. So, it is the translation unit that throws you the error.
Let's understand this by example.
#include "stdio.h"
int *ptr_i;
void func1()
{
static int i = 0;
ptr_i = &i;
i++;
printf("The static i=%d\r\n",i);
}
int main(int argc, char *argv[])
{
func1();
(*ptr_i)++;
func1();
}
The output of this program is the following.
The static i=1
The static i=3
As you could have understood, scope is not a run time. I was able to access the memory location used by i via pointer. Thus, you can access any memory in C as it is a flat memory structure. In this example, I accessed the memory of i using pointer to i. Note, Compiler never throw any error. Thus, scope is compile time not run time.
#include <stdio.h>
int call()
{
extern int b;
b=10;
printf("%d",b);
}
int main ()
{
int b=8;
call();
return 0;
}
Why is throwing an error like these do I get the following linker error:
/tmp/ccAsFhWX.o:meka.c:(.text+0x7): undefined reference to `_b' collect2: ld returned 1 exit status
I wanted to change the b value in the other function using extern keyword but it gives me an error.am i right in doing so ?
Declaring the extern int b declares it as.... extern. It must be defined elsewhere. If it isn't, drop the extern keyword?
I think you wanted a global variable:
#include <stdio.h>
static int b;
int call()
{
b=10;
printf("%d",b);
}
int main ()
{
b=8;
call();
return 0;
}
If you declare the global b as extern you gain the possibility (and the duty) to define it elsewhere (perhaps in another translation unit (helpers.c) or a library (helpers.a) etc.)
In the C programming language, an external variable is a variable defined outside any function block. Please read about extern variables (here, for example).
Also, variables have scopes. For example, it can be a local variable, a global variable etc. You can read more about that here.
So what you have done here is declared a function scope variable in function call () without defining it using the power of extern keyword. In other words, simply tells the compiler that variable already exists somewhere. On top of that, you declared and defined another function scope variable in function main (), which has the same name. It is important to understand that those variables are totally different. So at the end of day, when you link your program, the definition of the variable b for function call () is not found. You declared it but never defined, remember?
Here are possible solutions. Do not declare multiple b variables as that was clearly not your intent. Stick with a single declaration and definition:
#include <stdio.h>
extern int b;
void call()
{
b = 10;
printf("%d\n",b);
}
int b = 8;
int main () {
call();
return 0;
}
But global variables are usually very bad - global scope makes them extremely pipeline unfriendly, introduce threading issues etc. So you must look into something like this:
#include <stdio.h>
void call (int *b)
{
printf ("%d\n", *b = 10);
}
int main () {
int b = 8;
call (&b);
return 0;
}
I'd also recommend you read the following question and answers here. It explains a lot about extern variables in C.
And by the way, you function call () is declared with int return type but returns nothing.
Hope it helps!
To change the "b" in main(), you must pass a pointer to "call" like call (&b) and then do
void call (int *b) {
*b = 10;
printf("%d",*b);
}