In C language, scope of the static variable through out the file.
In the following code, function returns the static variable.
int fun(){
static int i = 10;
return i;
}
int main() {
printf("%d\n", fun());
return 0;
}
And printed output 10.
So, Is returning local static in C undefined behaviour or well-defined?
You seem to have missed the whole logic for a return statement.
In this snippet, you are actually returning the value (of the variable), so, without the static storage also, the code is fine.
In case, you want to return the address of a variable, it needs to outlast the scope of the function. In that case, you need to have a variable with static storage, so that the returned address is valid (so that it can be used meaningfully from the caller function) even outside the function in which it is defined. So, either
you use a pointer returned by allocator functions, like malloc() or family
use the address of a variable defined with static storage class.
Related
I recently learnt about the static variables, that they retain their values in between various function calls. Then I wrote some code to test it, then hopefully it worked perfect. But then I accidentally removed the static keyword at the beginning of the declaration of the local variable and there came the actual problem.
The output of both the programs are similar, besides the absence of the static keyword during the declaration.
Code without any static declaration:
#include <stdio.h>
void up();
int main(){
up(); //Output: 1
up(); //Output: 2
return 0;
}
void up(){
int stvar;
stvar++;
printf("%d\n", stvar);
}
Code with static declaration:
#include <stdio.h>
void up();
int main(){
up(); //Output: 1
up(); //Output: 2
return 0;
}
void up(){
static int stvar;
stvar++;
printf("%d\n", stvar);
}
Then finally I tried this one, by just initializing the local variable:
#include <stdio.h>
void up();
int main(){
up(); //Output: 1
up(); //Output: 1
return 0;
}
void up(){
int stvar = 0;
stvar++;
printf("%d\n", stvar);
}
This time the local variable shows it natural behaviour.
I just wanted to know if uninitialized local variables are static by default?
No, they are not static by default. In principle, the initial value can be anything at all. Using the value could even be undefined behaviour. In practice, the compiler picks a memory location for the variable on the stack, and the variable's initial value is whatever happens to already be in that memory location.
Since you don't run any other code between the first up() and the second up(), in practice your program is likely to pick the same location twice and therefore it still has the previous value. If you called another function in between, that function's local variables would go in the same space previously used by up()'s local variables, which would overwrite the value from the first up().
You certainly can't rely on it. Even if you don't call any other functions in-between, the compiler might add one "secretly" (for various reasons). Or the compiler may decide to adjust the stack between the two calls to up so each call might get a different stack location for its local variables.
You also aren't guaranteed that the first value is 0. Because it's whatever happens to be at that memory location already, it could be something left over from a previous function. main isn't the first function that gets called; there is some function in the standard library which does set-up work before it calls main.
Using non initialized automatic variable is dangerous.
It is Undefined Behavior if no address is taken.
Otherwise, like in your case the value of stvar would be indeterminate. It's value can be arbitrary, it may even change between accesses.
Always initialize local variables.
Note that variables with static storage (globals and static) are zero initialized if not initialized explicitly.
I'm getting this error while trying to define a local static variable.
Initializer element is not constant.
I want to retain the first value of var inside this recursion. How to pass this?
Hope you also clarify the side effects of assigning arguments to the local static variables to be prevented.
int function(int var)
{
static int index=var;
//some code ...
return var==0?1:function(var-1);
}
the static variable is initialized before the function even starts. It's like a global variable, only with function scope. The compiler cannot use a value that it doesn't know yet.
You could workaround this with an helper boolean:
int function(int var)
{
static int index_is_set=0;
static int index;
if (!index_is_set)
{
index = var;
index_is_set = 1;
}
//some code ...
return var==0?1:function(var-1);
}
so first time you enter the function it sets the value, sets the boolean flag to 1 so it's not overwritten by further calls.
note that this isn't very useful as a construct, since if you are to call your function recursively a second time in your program (after having obtained the result the first time, I mean), there's no way to reset the variable (unless you make index_is_set global so you can reset it from the outside).
Note that it is possible to get rid of all this static thing altogether by using the start value as an extra parameter.
int function(int var, int start_value)
{
// ...
return var==0 ? 1 : function(var-1,start_value);
}
First call goes like:
function(20,20);
or wrapped in a function which hides this implementation:
int function_wrapper(int var)
{
return function(var,var);
}
the start value is passed along all calls. Consumes a bit more auto variable space, but is much cleaner, no memory effect & easier to debug.
The case:
static int index=var;
Is a declaration with initializer (see ISO/IEC 9899:2011 §6.7 Declarations). The statement declares a static variable initialized to a value that must be a constant defined at compile time. In plain word because the value is initialized before the execution starts the initializer must be defined before function usage.
If you want retain the first value of a recursion the way you are using isn't a good choice for many reasons:
The value, as seen, cannot be assigned using a not constant value
If it worked, the next time you enter the function it would be reassigned clearing the very first value
A local static variable has unlimited life, but scope limited to the local function. Then you cannot access or initialize it from external scopes.
a solution can be to pass to the function 2 variables a first value and the value passing the same value the very first call of the function:
int function(int first_var, int var)
{
//some code ...
return var==0?1:function(first_var, var-1);
}
...
function(5, 5); //First call
For sake of completeness it could work by breaking your statement in a definition of the static variable without initialization (or with a generic initialization), followed by an assignment (ISO/IEC 9899:2011 §6.5.16 Assignment operators):
int function(int var)
{
static int index; //Declaration
index=var; //Assignement
//some code ...
return var==0?1:function(var-1);
}
But because it will be reassigned each time the function reenters, it is only a big nonsense...
I'm trying to fully understand how static variables work in C. I understand that using the static keyword makes the lifetime of the variable equal to the duration of the program. The following example has one thing that confuses me though...
My static_test.c file:
#include <stdio.h>
void foo(){
static int counter = 0;
counter++;
printf("This function has been called %i times.\n",counter);
return;
}
int main(){
int i;
for(i=0;i<10;i++){
foo();
}
return 0;
}
When I first read this example it makes me wonder why the function doesn't print out 0 every time since we are assigning 0 to the static variable.
Is this because once a static variable is declared the compiler ignores another declaration of the same variable on the next calls to my foo() function?
Thanks!
Despite the use of =, this is an initialization, NOT an assignment. So it happens when the variable is initialized and not when the 'statement' is apparently 'executed'. Since it is a static variable, it is initialized once when the program starts, rather than every time the function runs.
Static variables are initialized exactly once at program start, before your function is ever called. The fact that it's a local variable doesn't affect this rule.
In addition, static storage class variables are automatically initialized to zero if not explicitly initialized; the = 0 in your program is superfluous.
From the C11 drafts standard (ISO/IEC 9899:201x), section 6.2.4 Storage durations of objects, paragraph 3:
An object whose identifier is declared … with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
Yes, the compiler looks for an initial assignment after declaring a static variable and only executes it once, when the program starts.
This only happens when you declare the variable though. For example,
void foo(){
static int counter;
counter = 0;
counter++;
printf("This function has been called %i times.\n",counter);
return;
}
Would print 1 every time.
Static means the variable exists outside of the life time of the function. Think of it as a slightly clever global variable.
An 80k reputation contributor R.. told me on SO that we can't initialize global variables with the return value of a function as that's not considered a constant,and global variables must be initialized with a constant.And true to his words,I get the following error for this program as expected-- initializer element is not a constant.Here is the program:
#include<stdio.h>
int foo();
int gvar=foo(); //ERROR
int main()
{
printf("%d",gvar);
}
int foo()
{
return 8;
}
But in this context,I just don't understand why the followed altered version of the above program shows no error at all and works fine.In this second program,I am initializing the same global variable with the return value of the same function foo().Can you tell me what is the rigorous technical reason for this variation in results?Why is initializing the global variable with the return value of a function at it's declaration causing error but the same initialization with the same return value works fine when done from within a function?
#include<stdio.h>
int foo();
int gvar;
int main()
{
gvar=foo();
printf("%d",gvar);
}
int foo()
{
return 8;
}
Output 8
The reason behind it is that in order to determine a value produced by a function one needs to execute code, and that there is no code execution done in C when initializing static and global variables.
Compiler and linker work together to prepare a byte image of the global memory segment: the compiler provides the values, and the linker performs their final layout. At runtime, the image of the segment is loaded in memory as is, without further modifications. This happens before any code gets executed, so no function calls can be made.
Note that this does not mean that it is not possible for some technical reason, only that C designers decided against doing it. For example, C++ compiler generates a code segment that calls constructors of global objects, which gets executed before the control is passed to main().
The second version doesn't have an initializer for gvar. gvar is declared and defined at global scope without an initializer. It has static storage duration, so it is initialized with zero.
The assignment in main is just that: an assignment, not an initialization.
In case 1, global variable is assigned with a variable while it is declared.
But in the second case, global variable is assigned(which is already declared) with return value of foo().
Forming of data section, text section all happens during compilation.
Global variables will be in data section(bss or initialized data section), so at compile time, foo() is not invoked right? and return value of foo() is not known during compilation.
But second case, when the text section get executed, gvar is assigned with return value of foo(). It is valid.
You can maybe think of it like this: when main() starts, all global variables must already have their initializer values. And they can't, as you've been told, get those by calling functions since main() is really where execution starts, in a C program.
we could not call any function from outer of the function.Not like shell script.function only allow to called from inside of function body.
In c first execution begins from main(), compiler don't know the function calling if that stands on outer of function it may taken as prototype if arg and return types provided.
we can putting return value of function by calling from main or others function block, to the variable,the function called then (that global) variable modified.
but we can use macro in global variable as needs.
as:
#define max() 12
int glob=max();
main()
{
}
Suppose I have a static variable declared inside a function in C.
If I call that function multiple times, does the static variable get re-allocated in memory every time the function is called?
If it does get re-allocated, why is the last value always maintained?
Example:
void add()
{
static int x = 1;
x++;
printf("%d\n",x);
}
int main()
{
add(); // return 2
add(); // return 3
add(); // return 4
}
No - static variables are basically globals that live within the local namespace.
No, the variable is not reallocated everytime.
It is like having a global variable, but it only has local scope; i.e., you can only reference it from inside of that function.
No,
How else should it retain it's value between function calls?
Static variables are like global variables in this regard, however they are local to the surrounding scope (function, class, namespace).
The static variable is not re-allocated every time the function is called.
They act as normal local variables.
But they differ in storage duration i.e. when a function assigns some value to the static variables, that value is retained between function calls.
In the C programming language, static is used with global variables and functions to set their scope to the containing file. In local variables, static is used to store the variable in the statically allocated memory instead of the automatically allocated memory. While the language does not dictate the implementation of either type of memory, statically allocated memory is typically reserved in data segment of the program at compile time, while the automatically allocated memory is normally implemented as a transient call stack.
As the static prefix suggest the variable is in static memory that contains variables whose addresses is known at compile time (a somewhat pedantic way to say with global variables). That different from automatic variables (allocated on the stack) and dynamic variables (allocated on the heap using malloc).
The initialization of static variables in functions (or other static) is performed before the program is run. More precisely it means it can only be some constant expression, that the compiler can get at compile time.
That means the following program is not valid:
int f(int x){
return x+1;
}
int main(){
static int a = f(1);
return a;
}
When I compile it with gcc it complains as expected with the following message:
error: initializer element is not constant
However when the program run you can change the value of static variables as any other one.