question on static variable in a function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • subramanian100in@yahoo.com, India

    question on static variable in a function

    In the following link,


    The following ANSWER is given to a question(comp.l ang.c FAQ list ·
    Question 7.5a) :

    Whenever a function returns a pointer, make sure that the pointed-to
    memory is properly allocated. For example, make sure you have not done
    something like

    #include <stdio.h>

    char *itoa(int n)
    {
    char retbuf[20]; /* WRONG */
    sprintf(retbuf, "%d", n);
    return retbuf; /* WRONG */
    }

    When a function returns, its automatic, local variables are discarded,
    so the returned pointer in this case is invalid (it points to an array
    that no longer exists).

    One fix would be to declare the return buffer as

    static char retbuf[20];

    This fix is imperfect, since a function using static data is not
    reentrant.

    My question is what "reentrant" means here? Why is static data inside
    function discouraged ?

  • Kenny McCormack

    #2
    Re: question on static variable in a function

    In article <1173190666.435 341.9800@c51g20 00cwc.googlegro ups.com>,
    subramanian100i n@yahoo.com, India <subramanian100 in@yahoo.comwro te:
    ....
    >When a function returns, its automatic, local variables are discarded,
    >so the returned pointer in this case is invalid (it points to an array
    >that no longer exists).
    >
    >One fix would be to declare the return buffer as
    >
    > static char retbuf[20];
    >
    >This fix is imperfect, since a function using static data is not
    >reentrant.
    >
    >My question is what "reentrant" means here? Why is static data inside
    >function discouraged ?
    There are at least 3 things that can go wrong using this approach:
    1) The primary import of the phrase "not reentrant" is that it
    can't be used in a multi-threaded application. I.e., in a
    multi-thread, there could be more than one active
    invocation of the function.
    2) Functions with static data cannot be called recursively.
    3) The following code, although not involving either recursion
    or threading, doesn't work as expected:

    char *a,*b;
    a = afunc(someparam s);
    b = afunc(someparam s);
    /* Do something with a & b */

    It is actually #3 above that's the most annoying (IMHO).

    Comment

    • Ben Pfaff

      #3
      Re: question on static variable in a function

      "subramanian100 in@yahoo.com, India" <subramanian100 in@yahoo.com>
      writes:
      static char retbuf[20];
      >
      This fix is imperfect, since a function using static data is not
      reentrant.
      >
      My question is what "reentrant" means here? Why is static data inside
      function discouraged ?
      If you call the function twice, then the answer you get on the
      second call will replace the answer you get on the first call.
      Unless you make a copy of the value returned the first time, or
      you don't need to refer to it after the second call, this can be
      very surprising.

      This is not, strictly speaking, what "reentrant" is generally
      taken to mean, but it is the problem that you will encounter in
      this situation.
      --
      "C has its problems, but a language designed from scratch would have some too,
      and we know C's problems."
      --Bjarne Stroustrup

      Comment

      • subramanian100in@yahoo.com, India

        #4
        Re: question on static variable in a function

        I understand your points 1) and 3). But I have used static integer
        counter variable in a recursive method which works.

        I cannot understand the reason as to why recursive function
        cannot contain static data.

        Comment

        • bluejack

          #5
          Re: question on static variable in a function

          On Mar 6, 6:17 am, "subramanian10. ..@yahoo.com, India"
          <subramanian10. ..@yahoo.comwro te:
          >
          My question is what "reentrant" means here? Why is static data inside
          function discouraged ?
          Specifically, "reentrant" means that an application can re-enter the
          function while already executing the function, whether by recursion or
          in the execution of a different thread. This makes sense, right?
          Since static data persists across multiple executions of a function,
          if one line of execution is using that data and another modifies it,
          you are almost certainly going to encounter problems.

          Nor can variables declared static be relied upon to act as thread
          control flags (unless they are part of some well-crafted thread
          library that will very likely use implementation specific resources to
          guarantee thread safety). The following, for example, cannot be relied
          upon to work correctly:

          void do_some_multith readed_work(cha r* param) {
          static int active = 0;

          try_again:
          if (active) {
          goto try_again;
          } else {
          active = 1;
          /* do something to param */
          active = 0;
          }
          }

          Why? Because two threads could be so close together, that both would
          pass the "if (active)" test before either set active to 1. If you were
          trying to protect this because both threads might be working on the
          same character string pointed to by param, then you could have both
          threads acting on param at the same time, which is probably not what
          you want. Ok, not a *great* example, but you get the point, I hope.

          Recursion is a little different. A static int might be useful for
          counting your recursion depth, for example:

          void recursive_func( void) {
          static int depth = 0;
          depth++;
          if (depth 10) return;
          recursive_func( );
          }

          Ok, possibly an even worse example, if you think about it a little,
          but you see how the depth counter would work?

          What you wouldn't want in a recursive function would be static data
          that participates in the work of the function that calls itself (or
          can be called lower in the call chain from within this function).
          Sure, there are exceptions, but in general, you're asking for trouble.

          Data that is static within a function is a lot like an old fashioned
          global variable: it has many of the same drawbacks, and thus is
          generally discouraged. It doesn't have global scope, it can't be used
          willy nilly from everywhere, but as it spans both time and multiple
          lines of execution, it's a hazard.

          -Bluejack

          Comment

          • Lew Pitcher

            #6
            Re: question on static variable in a function

            On Mar 6, 9:17 am, "subramanian10. ..@yahoo.com, India"
            <subramanian10. ..@yahoo.comwro te:
            In the following link,http://www.c-faq.com/malloc/retaggr.html
            >
            The following ANSWER is given to a question(comp.l ang.c FAQ list ·
            Question 7.5a) :
            >
            Whenever a function returns a pointer, make sure that the pointed-to
            memory is properly allocated.
            [snip]
            When a function returns, its automatic, local variables are discarded,
            so the returned pointer in this case is invalid (it points to an array
            that no longer exists).
            >
            One fix would be to declare the return buffer as
            >
            static char retbuf[20];
            >
            This fix is imperfect, since a function using static data is not
            reentrant.
            >
            My question is what "reentrant" means here? Why is static data inside
            function discouraged ?
            Consider the following code fragments...

            #include <stdio.h>

            char *foo(int bar)
            {
            char baz[256];

            sprintf(baz,"%d ",bar);
            return baz;
            }

            void somefunc(void)
            {
            printf("%s, %s\n",foo(10),f oo(-999));
            }

            What will printf() in somefunc() print?
            Why?

            --
            Lew



            Comment

            • Chris Dollin

              #7
              Re: question on static variable in a function

              Kenny McCormack wrote:
              2) Functions with static data cannot be called recursively.
              I don't think that's what you mean to say, since they
              can, and further the effect of having a static can
              be useful. (Apart from scoping issues, it's the same
              as having the static outside the function, of course.)

              --
              Mobile Hedgehog
              A rock is not a fact. A rock is a rock.

              Comment

              • Lew Pitcher

                #8
                Re: question on static variable in a function

                A minor correction

                On Mar 6, 10:56 am, "Lew Pitcher" <lpitc...@sympa tico.cawrote:
                On Mar 6, 9:17 am, "subramanian10. ..@yahoo.com, India"
                >
                >
                >
                <subramanian10. ..@yahoo.comwro te:>
                The following ANSWER is given to a question(comp.l ang.c FAQ list ·
                Question 7.5a) :
                >
                Whenever a function returns a pointer, make sure that the pointed-to
                memory is properly allocated.
                [snip]
                When a function returns, its automatic, local variables are discarded,
                so the returned pointer in this case is invalid (it points to an array
                that no longer exists).
                >
                One fix would be to declare the return buffer as
                >
                static char retbuf[20];
                >
                This fix is imperfect, since a function using static data is not
                reentrant.
                >
                My question is what "reentrant" means here? Why is static data inside
                function discouraged ?
                >
                Consider the following code fragments...
                >
                #include <stdio.h>
                >
                char *foo(int bar)
                {
                char baz[256];
                Make that

                static char baz[256];

                Sorry :-S
                >
                sprintf(baz,"%d ",bar);
                return baz;
                }
                >
                void somefunc(void)
                {
                printf("%s, %s\n",foo(10),f oo(-999));
                }
                >
                What will printf() in somefunc() print?
                Why?
                >
                --
                Lew

                Comment

                • Mark McIntyre

                  #9
                  Re: question on static variable in a function

                  On 6 Mar 2007 06:17:46 -0800, in comp.lang.c ,
                  "subramanian100 in@yahoo.com, India" <subramanian100 in@yahoo.com>
                  wrote:

                  (of static local variables and their unsuitability )
                  >My question is what "reentrant" means here? Why is static data inside
                  >function discouraged ?
                  If you call the function in several different threads, or call it
                  recursively, or call it twice in a function argument list, you may get
                  peculiar answers, or even possibly a crash.

                  --
                  Mark McIntyre

                  "Debugging is twice as hard as writing the code in the first place.
                  Therefore, if you write the code as cleverly as possible, you are,
                  by definition, not smart enough to debug it."
                  --Brian Kernighan

                  Comment

                  • Kenny McCormack

                    #10
                    Re: question on static variable in a function

                    In article <QdgHh.73665$HO 5.52655@fe1.new s.blueyonder.co .uk>,
                    Chris Dollin <eh@electriched gehog.netwrote:
                    >Kenny McCormack wrote:
                    >
                    >2) Functions with static data cannot be called recursively.
                    >
                    >I don't think that's what you mean to say, since they
                    >can, and further the effect of having a static can
                    >be useful. (Apart from scoping issues, it's the same
                    >as having the static outside the function, of course.)
                    Others have addressed this. Short answer: Yes, I did mean it, but I
                    didn't go through all the necessary hoops to make it nitpick-proof.

                    Among others, Mark McI says:

                    If you call the function in several different threads, or call it
                    *recursively* (emphasis mine, Ed.) , or call it twice in a function
                    argument list, you may get peculiar answers, or even possibly a crash.

                    Comment

                    • CBFalconer

                      #11
                      Re: question on static variable in a function

                      "subramanian100 in@yahoo.com, India" wrote:
                      >
                      I understand your points 1) and 3). But I have used static integer
                      counter variable in a recursive method which works.
                      >
                      I cannot understand the reason as to why recursive function
                      cannot contain static data.
                      It can if you only call it once from outside, or if you don't use
                      the variable. I can think of other limited scenarios.

                      --
                      <http://www.cs.auckland .ac.nz/~pgut001/pubs/vista_cost.txt>
                      <http://www.securityfoc us.com/columnists/423>

                      "A man who is right every time is not likely to do very much."
                      -- Francis Crick, co-discover of DNA
                      "There is nothing more amazing than stupidity in action."
                      -- Thomas Matthews


                      Comment

                      • Richard Tobin

                        #12
                        Re: question on static variable in a function

                        In article <vuaru2pb1cq9mh pbjo33o5r9umg97 7k6mr@4ax.com>,
                        Mark McIntyre <markmcintyre@s pamcop.netwrote :
                        >If you call the function in several different threads, or call it
                        >recursively, or call it twice in a function argument list, you may get
                        >peculiar answers, or even possibly a crash.
                        Isn't it guaranteed that function calls in an argument list are called
                        without overlap?

                        -- Richard

                        --
                        "Considerat ion shall be given to the need for as many as 32 characters
                        in some alphabets" - X3.4, 1963.

                        Comment

                        • Mark McIntyre

                          #13
                          Re: question on static variable in a function

                          On 6 Mar 2007 23:30:12 GMT, in comp.lang.c , richard@cogsci. ed.ac.uk
                          (Richard Tobin) wrote:
                          >In article <vuaru2pb1cq9mh pbjo33o5r9umg97 7k6mr@4ax.com>,
                          >Mark McIntyre <markmcintyre@s pamcop.netwrote :
                          >>If you call the function in several different threads, or call it
                          >>recursively , or call it twice in a function argument list, you may get
                          >>peculiar answers, or even possibly a crash.
                          >
                          >Isn't it guaranteed that function calls in an argument list are called
                          >without overlap?
                          AFAIR the order in which they're evaluated is unspecified, so I
                          believe that

                          f1(f2(3), f2(2)) ;

                          might result in either f2(2) or f2(3) being evaluated first, or even
                          possibly both at once. I could probably construct a pathological
                          example of where this would matter but its not hard ot think of one.

                          --
                          Mark McIntyre

                          "Debugging is twice as hard as writing the code in the first place.
                          Therefore, if you write the code as cleverly as possible, you are,
                          by definition, not smart enough to debug it."
                          --Brian Kernighan

                          Comment

                          • Richard Tobin

                            #14
                            Re: question on static variable in a function

                            In article <mauru29qgak4i7 igu49f5i5mfstl6 u0mf9@4ax.com>,
                            Mark McIntyre <markmcintyre@s pamcop.netwrote :
                            >>Isn't it guaranteed that function calls in an argument list are called
                            >>without overlap?
                            >AFAIR the order in which they're evaluated is unspecified, so I
                            >believe that
                            >
                            > f1(f2(3), f2(2)) ;
                            >
                            >might result in either f2(2) or f2(3) being evaluated first,
                            Yes.
                            >or even possibly both at once.
                            Surely no, because there is a sequence point before each of the
                            functions is called.

                            -- Richard
                            --
                            "Considerat ion shall be given to the need for as many as 32 characters
                            in some alphabets" - X3.4, 1963.

                            Comment

                            • Dave Vandervies

                              #15
                              Re: question on static variable in a function

                              In article <mauru29qgak4i7 igu49f5i5mfstl6 u0mf9@4ax.com>,
                              Mark McIntyre <markmcintyre@s pamcop.netwrote :
                              >On 6 Mar 2007 23:30:12 GMT, in comp.lang.c , richard@cogsci. ed.ac.uk
                              >(Richard Tobin) wrote:
                              >
                              >>In article <vuaru2pb1cq9mh pbjo33o5r9umg97 7k6mr@4ax.com>,
                              >>Mark McIntyre <markmcintyre@s pamcop.netwrote :
                              >>>If you call the function in several different threads, or call it
                              >>>recursivel y, or call it twice in a function argument list, you may get
                              >>>peculiar answers, or even possibly a crash.
                              >>
                              >>Isn't it guaranteed that function calls in an argument list are called
                              >>without overlap?
                              >
                              >AFAIR the order in which they're evaluated is unspecified, so I
                              >believe that
                              >
                              > f1(f2(3), f2(2)) ;
                              >
                              >might result in either f2(2) or f2(3) being evaluated first, or even
                              >possibly both at once. I could probably construct a pathological
                              >example of where this would matter but its not hard ot think of one.
                              I believe that there are sequence points around the actual function call,
                              which would force them to not be interleaved modulo the as-if rule.

                              I seem to recall somebody pointing out to me that that didn't apply to
                              evaluation of the arguments, though, so
                              f1(f2(f2_args), f3(f3_args));
                              could happen as:
                              --------
                              evaluate f2 arguments }
                              evaluate f3 arguments } May be interleaved
                              (Sequence point)
                              call f2 >
                              (Sequence point) order not specified
                              call f3 >
                              (sequence point)
                              call f1
                              --------

                              So, f'rexample, something like:
                              --------
                              #include <stdio.h>
                              int foo(void)
                              {
                              static int i;
                              return i++;
                              }
                              int main(void)
                              {
                              printf("%d %d\n",foo(),foo ());
                              return 0;
                              }
                              --------
                              doesn't invoke undefined behavior (it must print either "1 2\n" or
                              "2 1\n"), but this one:
                              --------
                              #include <stdio.h>
                              int foo(int i) { return i; }
                              int main(void)
                              {
                              int i=0;
                              printf("%d %d\n",foo(i++), foo(i++));
                              return 0;
                              }
                              --------
                              is allowed to cause a rhinodaemon infestation.


                              dave

                              --
                              Dave Vandervies dj3vande@csclub .uwaterloo.ca
                              your a morron.
                              Beautiful. Classic sig block material.
                              --Richard Heathfield roasts a troll in comp.lang.c

                              Comment

                              Working...