doubt in static variables

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jeyshree
    New Member
    • Jul 2010
    • 75

    doubt in static variables

    hello,
    i am jeysree.i have a doubt.
    please look at the following two snippets.it doesnt shows any error
    Code:
    #include<stdio.h>
    #include<conio.h>
    void main()
    {
    static int a[10]={1,2,3,4,5};
    static int *p[10]={a,a+1,a+2,a+3,a+4};
    .
    .
    .
    .
    getch();
    }
    Code:
    void main()
    {
    static int a[10]={1,2,3,4,5};
    int *p[10]={a,a+1,a+2,a+3,a+4};
    .
    .
    .
    .
    .
    .
    getch();
    }
    the following two shows errors
    Code:
    void main()
    {
    int a[10]={1,2,3,4,5};
    int *p[10]={a,a+1,a+2,a+3,a+4};
    .
    .
    .
    .
    .
    getch();
    }
    Code:
    void main()
    {
    int a[10]={1,2,3,4,5};
    static int *p[10]={a,a+1,a+2,a+3,a+4};
    .
    .
    .
    .
    .
    getch();
    }
    please explain the use of static here.the error shown is illegal initialisation
    Last edited by Banfa; Jul 17 '10, 10:02 AM. Reason: Added [code] ... [/code] tags
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    #2
    Here is a simplified version of your snippets using CODE tags:
    Code:
    void sub1(void) {
       static int a = 1;
       static int *p = &a;
       }
    
    void sub2(void) {
       static int a = 1;
       int *p = &a;
       }
    
    void sub3(void) {
       int a = 1;
       static int *p = &a;
       }
    Variables defined within a block (such as within a function) can be either automatic or static. Automatic variables are instantiated at run-time each time the block is entered. Likewise, initial values for automatic variables are assigned at run-time each time the block is entered. Static variables are instantiated at compile-time. Initial values for static variables are magically assigned between the time you launch your program and when main is entered.

    Consider a recursive function that contains definitions for one automatic and one static variable. There is no relationship or interaction between the instances of the automatic variable created each time the function calls itself. However, all instances of the function refer to the same single static variable. One instance will see changes made to the static variable by another instance.

    The error you saw is a consequence of the difference between how initializers work for automatic and static variables. In all three examples, the definition of a is unremarkable. The error comes from the definition of pointer p, specifically the fact that its initializer is the address of a.
    • In sub1, p is a static variable. Thus its initial value must be known before the program starts to run. No problem, the address is known because a is also static.
    • In sub2, p is an automatic variable. The initial value must be known each time the function is entered. No problem, the addresses of both static and automatic variables are known at run-time.
    • In sub3, p is a static variable. The initial value must be known before the program starts to run. But now the initial value is the address of an automatic variable. Automatic variables don't exist until the function is called. There is no way to know what the address will be of something that doesn't exist yet.

    Comment

    • jeyshree
      New Member
      • Jul 2010
      • 75

      #3
      Originally posted by donbock
      Here is a simplified version of your snippets using CODE tags:
      Code:
      void sub1(void) {
         static int a = 1;
         static int *p = &a;
         }
      
      void sub2(void) {
         static int a = 1;
         int *p = &a;
         }
      
      void sub3(void) {
         int a = 1;
         static int *p = &a;
         }
      Variables defined within a block (such as within a function) can be either automatic or static. Automatic variables are instantiated at run-time each time the block is entered. Likewise, initial values for automatic variables are assigned at run-time each time the block is entered. Static variables are instantiated at compile-time. Initial values for static variables are magically assigned between the time you launch your program and when main is entered.

      Consider a recursive function that contains definitions for one automatic and one static variable. There is no relationship or interaction between the instances of the automatic variable created each time the function calls itself. However, all instances of the function refer to the same single static variable. One instance will see changes made to the static variable by another instance.

      The error you saw is a consequence of the difference between how initializers work for automatic and static variables. In all three examples, the definition of a is unremarkable. The error comes from the definition of pointer p, specifically the fact that its initializer is the address of a.
      • In sub1, p is a static variable. Thus its initial value must be known before the program starts to run. No problem, the address is known because a is also static.
      • In sub2, p is an automatic variable. The initial value must be known each time the function is entered. No problem, the addresses of both static and automatic variables are known at run-time.
      • In sub3, p is a static variable. The initial value must be known before the program starts to run. But now the initial value is the address of an automatic variable. Automatic variables don't exist until the function is called. There is no way to know what the address will be of something that doesn't exist yet.
      sir,
      thanks for your reply.i just want to know when and where is memory allocated for static variables declared locally and globally?
      also i wish to know when and where is memory allocated for other global variables other than static?
      this would help me to understand better.

      Comment

      • jeyshree
        New Member
        • Jul 2010
        • 75

        #4
        Originally posted by donbock
        Here is a simplified version of your snippets using CODE tags:
        Code:
        void sub1(void) {
           static int a = 1;
           static int *p = &a;
           }
        
        void sub2(void) {
           static int a = 1;
           int *p = &a;
           }
        
        void sub3(void) {
           int a = 1;
           static int *p = &a;
           }
        Variables defined within a block (such as within a function) can be either automatic or static. Automatic variables are instantiated at run-time each time the block is entered. Likewise, initial values for automatic variables are assigned at run-time each time the block is entered. Static variables are instantiated at compile-time. Initial values for static variables are magically assigned between the time you launch your program and when main is entered.

        Consider a recursive function that contains definitions for one automatic and one static variable. There is no relationship or interaction between the instances of the automatic variable created each time the function calls itself. However, all instances of the function refer to the same single static variable. One instance will see changes made to the static variable by another instance.

        The error you saw is a consequence of the difference between how initializers work for automatic and static variables. In all three examples, the definition of a is unremarkable. The error comes from the definition of pointer p, specifically the fact that its initializer is the address of a.
        • In sub1, p is a static variable. Thus its initial value must be known before the program starts to run. No problem, the address is known because a is also static.
        • In sub2, p is an automatic variable. The initial value must be known each time the function is entered. No problem, the addresses of both static and automatic variables are known at run-time.
        • In sub3, p is a static variable. The initial value must be known before the program starts to run. But now the initial value is the address of an automatic variable. Automatic variables don't exist until the function is called. There is no way to know what the address will be of something that doesn't exist yet.
        sir,
        thanks for your reply.i just want to know when and where is memory allocated for static variables declared locally and globally?
        also i wish to know when and where is memory allocated for other global variables other than static?
        this would help me to understand better.

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          I don't know what you mean by "static variables declared locally" or "static variables declared globally". A common source of confusion is how the keyword static is used for both linkage and storage duration.

          Linkage applies to a variable's name. There are three kinds of linkage: external, internal, and none. External linkage means the name can be used in different source files to reference the same variable (that is, a global variable). Internal linkage means references to the variable name always refer to an instance of the variable local to the source file, The static keyword always establishes internal linkage. No linkage refers to function parameters and automatic variables.

          Duration applies to a variable itself. There are three kinds of duration: static, automatic, and allocated. Variables with static duration exist for the entire duration of the program, from start to finish. Variables with automatic duration exist while execution remains within scope of the definition. Variables with allocated duration exist from the time they are explicitly allocated until they are explicitly freed. All variables declared with the static keyword plus all variables with external linkage have static duration. That is, all variables except function parameters and automatic variables have static duration.

          My guess is that both "static variables declared locally" and "static variables declared globally" refer to variables with static duration. In that case, the variables are allocated and initialized automatically before the first line of your program is executed; and they persist until your program ends. Does this answer your question?

          Comment

          • jeyshree
            New Member
            • Jul 2010
            • 75

            #6
            Originally posted by donbock
            I don't know what you mean by "static variables declared locally" or "static variables declared globally". A common source of confusion is how the keyword static is used for both linkage and storage duration.

            Linkage applies to a variable's name. There are three kinds of linkage: external, internal, and none. External linkage means the name can be used in different source files to reference the same variable (that is, a global variable). Internal linkage means references to the variable name always refer to an instance of the variable local to the source file, The static keyword always establishes internal linkage. No linkage refers to function parameters and automatic variables.

            Duration applies to a variable itself. There are three kinds of duration: static, automatic, and allocated. Variables with static duration exist for the entire duration of the program, from start to finish. Variables with automatic duration exist while execution remains within scope of the definition. Variables with allocated duration exist from the time they are explicitly allocated until they are explicitly freed. All variables declared with the static keyword plus all variables with external linkage have static duration. That is, all variables except function parameters and automatic variables have static duration.

            My guess is that both "static variables declared locally" and "static variables declared globally" refer to variables with static duration. In that case, the variables are allocated and initialized automatically before the first line of your program is executed; and they persist until your program ends. Does this answer your question?
            sir,
            some of the persons banfa,weaknessf orcats in bytes.com replied that memory will be allocated for static variables inside function only at first time function is called.i am confused.the answers are in
            allocation of memory
            which i posted.please explain

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              I should rephrase my last paragraph:

              My guess is that both "static variables declared locally" and "static variables declared globally" refer to variables with static duration. In that case, it is as if the variables are allocated and initialized automatically before the first line of your program is executed; and they persist until your program ends. Does this answer your question?

              Comment

              • weaknessforcats
                Recognized Expert Expert
                • Mar 2007
                • 9214

                #8
                What error are you getting on your example using the static keyword?

                As to your file types:

                The .c is the text file withour code in it.

                The .obj is the compiled version of the .c file.

                If you program has 10 .c files then you will also have 10 .obj files.

                The .exe file is created by the linker from the .obj files. The .exe is your executable program.

                If you program has 10 .objh files then there will be a copy of each .obj placed in the .exe.

                Then the linker then adds startup code to the .exe and resolves all missing addresses.

                The .i files are the intermediate files created by the preprocessor from the .c files. Each .c is processed by the preprocessor and all of your #include result in a copy of the included file placed right where you coded the #include. This expanded .c file (the .i file) is called a translation unit and it is this file that is actually compiled.

                Comment

                • donbock
                  Recognized Expert Top Contributor
                  • Mar 2008
                  • 2427

                  #9
                  Originally posted by jeyshree
                  hello,
                  please look at the following two snippets.it doesnt shows any error
                  #include<stdio. h>
                  #include<conio. h>
                  void main()
                  {
                  static int a[10]={1,2,3,4,5};
                  static int *p[10]={a,a+1,a+2,a+3 ,a+4};
                  .
                  .
                  .
                  .
                  getch();
                  }
                  #include<stdio. h>
                  #include<conio. h>
                  void main()
                  {
                  static int a[10]={1,2,3,4,5};
                  int *p[10]={a,a+1,a+2,a+3 ,a+4};
                  .
                  .
                  .
                  .
                  .
                  .
                  getch();
                  }
                  the following two shows errors
                  #include<stdio. h>
                  #include<conio. h>
                  void main()
                  {
                  int a[10]={1,2,3,4,5};
                  int *p[10]={a,a+1,a+2,a+3 ,a+4};
                  .
                  .
                  .
                  .
                  .
                  getch();
                  }
                  #include<stdio. h>
                  #include<conio. h>
                  void main()
                  {
                  int a[10]={1,2,3,4,5};
                  static int *p[10]={a,a+1,a+2,a+3 ,a+4};
                  .
                  .
                  .
                  .
                  .
                  getch();
                  }
                  please explain the use of static here.the error shown is illegal initialisation for last two snippets
                  This same compiler error was the basis of one of your other threads. Didn't this reply explain why the error occurred?

                  Whether or not you believe in "compile-time" variable allocation, the fact remains that static variables are initialized once, before any instructions in that block are executed. Thus initial values for static variables have to be unambiguously defined before execution begins.

                  Comment

                  • jeyshree
                    New Member
                    • Jul 2010
                    • 75

                    #10
                    Originally posted by weaknessforcats
                    Lety me ask you a question:

                    If you compile on machine A and run the program on machine B, then how can memory be allocated at compile time on machine A?

                    Obviously, all memory is allocated at run time.

                    The compiler only generates the code to do the allocating but does not do the actual allocating.

                    It's not that hard:
                    1) variables outsode functions are allocated at run time before main() starts.
                    2) variables inside functions are allocated when the function is called. In C++ there will be variables allocated after the function is called but before it completes.

                    A static variable inside a function is not kept with the other variables since it does not belong to a specific function call. Instead, this static variable is kept in an area of memory that will not be deallocated when the function completes.

                    The compiler generates code to create an initialize the static variable on the first call and on all opther calls, generates code that uses the same variable created on the first call.

                    Remember, you are not running the program when you compile it.
                    Hello,
                    You say that memory for all variables will be allocated at run time only and compiler only generates code to allocate memory while compiling.Is it true for variables allocated using malloc and calloc(actually they say that it is dynamic memory allocation).Is run time alloction and dynamic memory allocation same?

                    Comment

                    • jeyshree
                      New Member
                      • Jul 2010
                      • 75

                      #11
                      Originally posted by weaknessforcats
                      What error are you getting on your example using the static keyword?

                      As to your file types:

                      The .c is the text file withour code in it.

                      The .obj is the compiled version of the .c file.

                      If you program has 10 .c files then you will also have 10 .obj files.

                      The .exe file is created by the linker from the .obj files. The .exe is your executable program.

                      If you program has 10 .objh files then there will be a copy of each .obj placed in the .exe.

                      Then the linker then adds startup code to the .exe and resolves all missing addresses.

                      The .i files are the intermediate files created by the preprocessor from the .c files. Each .c is processed by the preprocessor and all of your #include result in a copy of the included file placed right where you coded the #include. This expanded .c file (the .i file) is called a translation unit and it is this file that is actually compiled.
                      Hello,
                      I cant understand the word "linker" here.What is the use of linker (as you used in the following line)?

                      "The .exe file is created by the linker from the .obj files."

                      I merely cant understand the line
                      "If you program has 10 .objh files then there will be a copy of each .obj placed in the .exe."
                      Will there be many .obj files created for single .c program?

                      Why do use the word address in the forecoming statement?Does code to allocate memory take place here as you said (in the previous reply)?This doubt came to me because you told me in your previous reply that code to allocate memory will take place at compile time?
                      "Then the linker then adds startup code to the .exe and resolves all missing addresses."

                      The .i files are the intermediate files created by the preprocessor from the .c files. Each .c is processed by the preprocessor and all of your #include result in a copy of the included file placed right where you coded the #include. This expanded .c file (the .i file) is called a translation unit and it is this file that is actually compiled.

                      Comment

                      • jeyshree
                        New Member
                        • Jul 2010
                        • 75

                        #12
                        Originally posted by donbock
                        Here is a simplified version of your snippets using CODE tags:
                        Code:
                        void sub1(void) {
                           static int a = 1;
                           static int *p = &a;
                           }
                        
                        void sub2(void) {
                           static int a = 1;
                           int *p = &a;
                           }
                        
                        void sub3(void) {
                           int a = 1;
                           static int *p = &a;
                           }
                        Variables defined within a block (such as within a function) can be either automatic or static. Automatic variables are instantiated at run-time each time the block is entered. Likewise, initial values for automatic variables are assigned at run-time each time the block is entered. Static variables are instantiated at compile-time. Initial values for static variables are magically assigned between the time you launch your program and when main is entered.

                        Consider a recursive function that contains definitions for one automatic and one static variable. There is no relationship or interaction between the instances of the automatic variable created each time the function calls itself. However, all instances of the function refer to the same single static variable. One instance will see changes made to the static variable by another instance.

                        The error you saw is a consequence of the difference between how initializers work for automatic and static variables. In all three examples, the definition of a is unremarkable. The error comes from the definition of pointer p, specifically the fact that its initializer is the address of a.
                        • In sub1, p is a static variable. Thus its initial value must be known before the program starts to run. No problem, the address is known because a is also static.
                        • In sub2, p is an automatic variable. The initial value must be known each time the function is entered. No problem, the addresses of both static and automatic variables are known at run-time.
                        • In sub3, p is a static variable. The initial value must be known before the program starts to run. But now the initial value is the address of an automatic variable. Automatic variables don't exist until the function is called. There is no way to know what the address will be of something that doesn't exist yet.
                        Hello sir,
                        I get you sir .But many people still say memory to static variable inside a function will be allocated when it enters the function for the first time?If i take in that way
                        void sub3(void) {
                        int a = 1;
                        static int *p = &a;
                        }
                        should not throw any error.because static is allocated memory only after function is called and after memory for a is allocated.i now cant get into the final conclusion

                        Comment

                        • jeyshree
                          New Member
                          • Jul 2010
                          • 75

                          #13
                          Originally posted by donbock
                          I don't know what you mean by "static variables declared locally" or "static variables declared globally". A common source of confusion is how the keyword static is used for both linkage and storage duration.

                          Linkage applies to a variable's name. There are three kinds of linkage: external, internal, and none. External linkage means the name can be used in different source files to reference the same variable (that is, a global variable). Internal linkage means references to the variable name always refer to an instance of the variable local to the source file, The static keyword always establishes internal linkage. No linkage refers to function parameters and automatic variables.

                          Duration applies to a variable itself. There are three kinds of duration: static, automatic, and allocated. Variables with static duration exist for the entire duration of the program, from start to finish. Variables with automatic duration exist while execution remains within scope of the definition. Variables with allocated duration exist from the time they are explicitly allocated until they are explicitly freed. All variables declared with the static keyword plus all variables with external linkage have static duration. That is, all variables except function parameters and automatic variables have static duration.

                          My guess is that both "static variables declared locally" and "static variables declared globally" refer to variables with static duration. In that case, the variables are allocated and initialized automatically before the first line of your program is executed; and they persist until your program ends. Does this answer your question?
                          Hello,
                          You say memory for static variable inside a function will be allcated only at first time the function is called? Then why should the following code throw an error"illegal initialisation" .
                          void main()
                          {
                          int a[10]={1,2,3,4,5};
                          static int *p[10]={a,a+1,a+2,a+3 ,a+4};
                          .
                          .
                          .
                          .
                          .
                          getch();
                          }
                          please explain.

                          Comment

                          • jeyshree
                            New Member
                            • Jul 2010
                            • 75

                            #14
                            Originally posted by jeyshree
                            Hello,
                            You say memory for static variable inside a function will be allcated only at first time the function is called? Then why should the following code throw an error"illegal initialisation" .
                            void main()
                            {
                            int a[10]={1,2,3,4,5};
                            static int *p[10]={a,a+1,a+2,a+3 ,a+4};
                            .
                            .
                            .
                            .
                            .
                            getch();
                            }
                            please explain.
                            Sorry sir
                            I sent you the massage instead of sending for weaknessforcats .Please forgive me

                            Comment

                            • donbock
                              Recognized Expert Top Contributor
                              • Mar 2008
                              • 2427

                              #15
                              I'm the one who first spoke of static variables being allocated at compile time. Let me explain what I meant. First of all, everything I am about to say is about C compilers -- things might work quite differently for C++. (Which are you using?) All of the C compilers I've worked with generate object files containing three memory segments: text, data, and bss. The text segment contains all of the executable code. The data segment contains all of the initialized variables that have static duration. The bss segment contains all of the uninitialized variables that have static duration. When I said "static variables are allocated at compile time" I was referring to the compiler defining a chunk of data or bss segment large enough to hold the variable. Weaknessforcats was right to point out that this is implementation-specific behavior that is not followed by all compiler implementations . Now that I've explained ... forget all about "compile-time allocation", it isn't really pertinent to why you get those compiler errors.

                              Code:
                              void sub3(void) { 
                                 int a = 1; 
                                 static int *p = &a; 
                              }
                              The initializer for variable p is illegal because the C Standard says it is illegal. Much of my earlier discussion was aimed at explaining why the Standard would make this illegal -- but that's not important. What's important is that it is illegal because the Standard says it is illegal: the initializer for a static variable is not allowed to be the address of an automatic variable. If I had access to my copy of the C Standard I would quote it for you.

                              Comment

                              Working...