Static variable inside of a function in C
Asked Answered
C

15

156

What will be printed out? 6 6 or 6 7? And why?

void foo()
{
    static int x = 5;
    x++;
    printf("%d", x);
}

int main()
{
    foo();
    foo();
    return 0;
}
Cotidal answered 17/2, 2011 at 19:31 Comment(7)
What's the problem to try?Meyerhof
Did you try to type this in and see for yourself?Scyphus
ideone.com/t9Bbe What would you expect? Does the result not match your expection? Why did you expect your result?Patricepatrich
becase the x increased before it is printed the console will say 6 and 7.Semitone
superset #573047Safelight
What really confused me is how this worked with function created data, as portable C requires all declarations to precede definition, but static variables need do be declared at once. In particulara, I had doubts how a statement like static HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); in the middle of a function would work. it doesn't, error: initializer element is not constant. Inspection in objdump showed me that static variable was actually moved to global scope. I wonder why it doesnt let functions be declared this way, would be convenient for callback functions.Geotaxis
It is fun that people say that the output is 6 7, 6,7 etc, but nobody says that it is 67Jost
H
243

There are two issues here, lifetime and scope.

The scope of variable is where the variable name can be seen. Here, x is visible only inside function foo().

The lifetime of a variable is the period over which it exists. If x were defined without the keyword static, the lifetime would be from the entry into foo() to the return from foo(); so it would be re-initialized to 5 on every call.

The keyword static acts to extend the lifetime of a variable to the lifetime of the programme; e.g. initialization occurs once and once only and then the variable retains its value - whatever it has come to be - over all future calls to foo().

Hebron answered 17/2, 2011 at 19:34 Comment(7)
in what scenarios we need to declare a variable as static inside a function?, just curious to know as I haven't used this before?Illona
i'd say thanks, but this was all answered at the very tip top of the page. it makes me laugh that people don't just run their own code. xDHightail
This answer is wrong. The moment you think about recursive functions the definitions as described here do not explain the behavior!Douce
What happens if I declare a static variable and then initialize on a separate line like so: static int a; a = 0; In this case, a would be reset to 0 each time. Is that correct?Jolin
@LakshyaGoyal Your second line is a statement, not an initialization. So yes, you are correct that a would be zero (immediately after the 2nd line is ran) each time. This would, of course, likely negate the benefits of using a static variable.Danger
@Illona the scenario would be similar to having a static private field in a class. Since C is not object oriented these types of variables help with encapsulation, otherwise you should use a global variable. But basically it's a variable whose value you want to keep between calls to the function.Contemptuous
@Hightail distinguish 'what the version of the C compiler that I am using today happened to do, with my current compiler switches' from 'according to the C language specification'.Crepuscule
K
80

Output: 6 7

Reason: static variable is initialised only once (unlike auto variable) and further definition of static variable would be bypassed during runtime. And if it is not initialised manually, it is initialised by value 0 automatically. So,

void foo() {
    static int x = 5; // assigns value of 5 only once
    x++;
    printf("%d", x);
}

int main() {
    foo(); // x = 6
    foo(); // x = 7
    return 0;
}
Kermis answered 21/5, 2014 at 8:24 Comment(0)
M
13

That is the same as having the following program:

static int x = 5;

void foo()
{
    x++;
    printf("%d", x);
}

int main()
{
     foo();
     foo();
     return 0;
}

All that the static keyword does in that program is it tells the compiler (essentially) 'hey, I have a variable here that I don't want anyone else accessing, don't tell anyone else it exists'.

Inside a method, the static keyword tells the compiler the same as above, but also, 'don't tell anyone that this exists outside of this function, it should only be accessible inside this function'.

I hope this helps

Messeigneurs answered 17/2, 2011 at 19:37 Comment(4)
Well, it's not actually the same. There's still the issue of scope on X. In this example, you could poke and futz with x in main; it is global. In the original example x was local to foo, only visible while inside that block, which is generally preferable: if foo exists to maintain x in predictable and visible ways, then letting others poke it is generally dangerous. As another benefit of keeping it in scope foo() It also keeps foo() portable.Pape
@Pape 'don't tell anyone that this exists outside of this function, it should only be accessible inside this function'Scala
While you've addressed the issue of scope due to where the variable is declared, the description of static as affecting scope, rather than lifetime, seems incorrect.Scala
@Chameleon The question is tagged as c, so in this context, your example would be illegal at global scope. (C requires constant initializers for globals, C++ does not).Messeigneurs
H
11

6 7

compiler arranges that static variable initialization does not happen each time the function is entered

Head answered 17/2, 2011 at 19:34 Comment(0)
M
8

Output: 6,7

Reason

The declaration of x is inside foo but the x=5 initialization takes place outside of foo!

What we need to understand here is that

static int x = 5;

is not the same as

static int x;
x = 5;

Other answers have used the important words here, scope and lifetime, and pointed out that the scope of x is from the point of its declaration in the function foo to the end of the function foo. For example I checked by moving the declaration to the end of the function, and that makes x undeclared at the x++; statement.

So the static int x (scope) part of the statement actually applies where you read it, somewhere INSIDE the function and only from there onwards, not above it inside the function.

However the x = 5 (lifetime) part of the statement is initialization of the variable and happening OUTSIDE of the function as part of the program loading. Variable x is born with a value of 5 when the program loads.

I read this in one of the comments: "Also, this doesn't address the really confusing part, which is the fact that the initializer is skipped on subsequent calls." It is skipped on all calls. Initialization of the variable is outside of the function code proper.

The value of 5 is theoretically set regardless of whether or not foo is called at all, although a compiler might optimize the function away if you don't call it anywhere. The value of 5 should be in the variable before foo is ever called.

Inside of foo, the statement static int x = 5; is unlikely to be generating any code at all.

I found the address x uses when I put a function foo into a program of mine, and then (correctly) guessed that the same location would be used if I ran the program again. The partial screen capture below shows that x has the value 5 even before the first call to foo.

Break Point before first call to foo

Mudslinging answered 5/3, 2018 at 11:35 Comment(0)
C
5

A static variable inside a function has a lifespan as long as your program runs. It won't be allocated every time your function is called and deallocated when your function returns.

Collaboration answered 17/2, 2011 at 19:49 Comment(2)
Saying this is like a "global" variable and then saying EXCEPT you can't access it is an oxymoron. Global means accessible anywhere. Which in this case of a static INSIDE a function it is NOT accessible everywhere. The issue in OP as others have noted is about scope and lifetime. Please don't confuse folks with using the term 'global' and misleading them on the scope of the variable.Persevering
@ChuckB: Correct. Fixed it. Well it's been 6 years. My previous answer had the perception of 6 years ago!Collaboration
O
4

Let's just read the Wikipedia article on Static Variables...

Static local variables: variables declared as static inside a function are statically allocated while having the same scope as automatic local variables. Hence whatever values the function puts into its static local variables during one call will still be present when the function is called again.

Osier answered 17/2, 2011 at 19:34 Comment(4)
That's terrible! "variables declared as static inside a function are statically allocated" - it explains nothing, unless you already know what it means!Hebron
@Blank: well, that's what I thought the second sentence was for. Though I guess you're right, it should be better worded.Osier
Also, this doesn't address the really confusing part, which is the fact that the initializer is skipped on subsequent calls.Tartarous
statically allocated means no stack, nor heap.Senaidasenalda
C
3

Vadiklk,

Why ...? Reason is that static variable is initialized only once, and maintains its value throughout the program. means, you can use static variable between function calls. also it can be used to count "how many times a function is called"

main()
{
   static int var = 5;
   printf("%d ",var--);
   if(var)
      main();
} 

and answer is 5 4 3 2 1 and not 5 5 5 5 5 5 .... (infinite loop) as you are expecting. again, reason is static variable is initialized once, when next time main() is called it will not be initialize to 5 because it is already initialized in the program.So we can change the value but can not reinitialized. Thats how static variable works.

or you can consider as per storage: static variables are stored on Data Section of a program and variables which are stored in Data Section are initialized once. and before initialization they are kept in BSS section.

In turn Auto(local) variables are stored on Stack and all the variables on stack reinitialized all time when function is called as new FAR(function activation record) is created for that.

okay for more understanding, do the above example without "static" and let you know what will be the output. That make you to understand the difference between these two.

Thanks Javed

Chronology answered 5/12, 2013 at 9:1 Comment(0)
R
2

The output will be 6 7. A static variable (whether inside a function or not) is initialized exactly once, before any function in that translation unit executes. After that, it retains its value until modified.

Resistive answered 17/2, 2011 at 19:35 Comment(3)
Are you sure the static is initialised before the function is called, and not upon first call of the function?Bite
@JessePepper: At least if memory serves, this depends on whether you're talking about C++98/03 or C++11. In C++98/03, I believe it's as described above. In C++11, threading makes that essentially impossible to do, so initialization is done on first entry to the function.Resistive
I think you're wrong actually. I think even pre C++11 it was only initialised when the function is called. This is important for a common solution to the static initialisation dependency problem.Bite
H
1

You will get 6 7 printed as, as is easily tested, and here's the reason: When foo is first called, the static variable x is initialized to 5. Then it is incremented to 6 and printed.

Now for the next call to foo. The program skips the static variable initialization, and instead uses the value 6 which was assigned to x the last time around. The execution proceeds as normal, giving you the value 7.

Heth answered 17/2, 2011 at 19:36 Comment(0)
L
1
6 7

x is a global variable that is visible only from foo(). 5 is its initial value, as stored in the .data section of the code. Any subsequent modification overwrite previous value. There is no assignment code generated in the function body.

Ladd answered 17/2, 2011 at 19:37 Comment(0)
L
1

6 and 7 Because static variable intialise only once, So 5++ becomes 6 at 1st call 6++ becomes 7 at 2nd call Note-when 2nd call occurs it takes x value is 6 instead of 5 because x is static variable.

Lombroso answered 7/6, 2014 at 5:25 Comment(0)
A
0

In C++11 at least, when the expression used to initialize a local static variable is not a 'constexpr' (cannot be evaluated by the compiler), then initialization must happen during the first call to the function. The simplest example is to directly use a parameter to intialize the local static variable. Thus the compiler must emit code to guess whether the call is the first one or not, which in turn requires a local boolean variable. I've compiled such example and checked this is true by seeing the assembly code. The example can be like this:

void f( int p )
{
  static const int first_p = p ;
  cout << "first p == " << p << endl ;
}

void main()
{
   f(1); f(2); f(3);
}

of course, when the expresion is 'constexpr', then this is not required and the variable can be initialized on program load by using a value stored by the compiler in the output assembly code.

Aroid answered 11/1, 2019 at 10:44 Comment(0)
T
0

Share what I learned about this point.

In C static is a declaration specifier, which falls into three categories:

  • storage classes: there are four classes: auto, static, extern and register.
  • type qualifiers: like keywords: const, volatile, etc.
  • type specifiers: like keywords: void, char, short, int, etc.

So static is a storage classes. It will determine the following three properties of each variable in a C program.

  • storage duration: means when memory is allocated for the variable and when the memory is released. A variable with static storage duration stays at the same memory location as long as the program is running.
  • scope: means the portion of the program text in which the variable can be accessed.
  • linkage: means the extent to which the variable can be shared by different parts(or files) of a program.

The static storage class has a different effect on a variable depending on it is declared outside a block or inside a block. Let's focus on the case when a static variable declared within a block(the one discussed in this post).

  • A static variable in a block is initialized only once.
  • If a function is called multiple times, the static block variable is shared by all calls of the function.

This understanding is based on the book "c programming a modern approach"

Tancred answered 27/7, 2022 at 8:37 Comment(0)
T
0

Output is both 6 and 7. As the static variable is initialized only once. Here it is initialized to 5 and after that, it would be incremented by each ++ operation.

Topography answered 8/3 at 11:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.