Using static to init vars?

Discussion in 'C Programming' started by Ronald Bruck, Jun 12, 2006.

  1. Ronald Bruck

    Ronald Bruck Guest

    I have several routines which are used millions of times in my
    programs, using the Gnu multi-precision software's floating-point reals
    (see <http://www.swox.se/gmp>). These are of type mpf_t, and I must
    explicitly initialize (and later free) all temporary variables of this
    type.

    So I hit on the idea of something like this:

    static int firstcall = 1;
    mpf_t temp;

    if (firstcall) {
    firstcall = 0;
    mpf_init(temp);
    }
    else blahblah

    First time through, firstcall is 1, so temp gets initialized. Second
    (and later) times through, temp is already initialized (with what
    values I don't care, because i'll reset them) and doesn't get
    REinitialized (which would be a fatal error).

    It passes -Wall, and it seems to work. Is it legal? Is there anything
    I need to look out for?

    Initializing, and then freeing, an mpf_t millions of times is not
    something I want to do. Especially since it may be thousands of bytes
    long.

    I should add, I don't care that I never free temp. The program exits
    before this would become a problem.

    --Ron Bruck

    Posted Via Usenet.com Premium Usenet Newsgroup Services
    ----------------------------------------------------------
    ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
    ----------------------------------------------------------
    http://www.usenet.com
    Ronald Bruck, Jun 12, 2006
    #1
    1. Advertising

  2. In article <120620061031319493%>,
    Ronald Bruck <> wrote:

    >So I hit on the idea of something like this:


    > static int firstcall = 1;
    > mpf_t temp;


    > if (firstcall) {
    > firstcall = 0;
    > mpf_init(temp);
    > }
    > else blahblah


    >First time through, firstcall is 1, so temp gets initialized. Second
    >(and later) times through, temp is already initialized (with what
    >values I don't care, because i'll reset them) and doesn't get
    >REinitialized (which would be a fatal error).


    >It passes -Wall, and it seems to work. Is it legal? Is there anything
    >I need to look out for?


    Yes, that is legal.

    You could also save an assignment by reversing the sense of the flag
    (statics are automatically initialized to 0). If you did that, though,
    your if would have to be against !flagname and whether that generated
    more instructions than just testing flagname without the logical
    negation would be dependant on the optimizer.
    --
    Prototypes are supertypes of their clones. -- maplesoft
    Walter Roberson, Jun 12, 2006
    #2
    1. Advertising

  3. Ronald Bruck

    Al Balmer Guest

    On Mon, 12 Jun 2006 10:31:31 -0700, Ronald Bruck <>
    wrote:

    >I have several routines which are used millions of times in my
    >programs, using the Gnu multi-precision software's floating-point reals
    >(see <http://www.swox.se/gmp>). These are of type mpf_t, and I must
    >explicitly initialize (and later free) all temporary variables of this
    >type.
    >
    >So I hit on the idea of something like this:
    >
    > static int firstcall = 1;
    > mpf_t temp;
    >
    > if (firstcall) {
    > firstcall = 0;
    > mpf_init(temp);
    > }
    > else blahblah
    >
    >First time through, firstcall is 1, so temp gets initialized. Second
    >(and later) times through, temp is already initialized (with what
    >values I don't care, because i'll reset them) and doesn't get
    >REinitialized (which would be a fatal error).
    >
    >It passes -Wall, and it seems to work. Is it legal? Is there anything
    >I need to look out for?


    Sure. I use this technique often, because a caller can just use the
    function without needing to know whether it's been initialized or not,
    or whether some other function has already done the job.

    This is analogous to data hiding techniques - consider that the
    calling function has no need to know the state of the called function,
    only that it will do the job requested.
    >
    >Initializing, and then freeing, an mpf_t millions of times is not
    >something I want to do. Especially since it may be thousands of bytes
    >long.
    >
    >I should add, I don't care that I never free temp. The program exits
    >before this would become a problem.
    >
    >--Ron Bruck
    >
    > Posted Via Usenet.com Premium Usenet Newsgroup Services
    >----------------------------------------------------------
    > ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
    >----------------------------------------------------------
    > http://www.usenet.com


    --
    Al Balmer
    Sun City, AZ
    Al Balmer, Jun 12, 2006
    #3
  4. Ronald Bruck

    Eric Sosman Guest

    Ronald Bruck wrote On 06/12/06 13:31,:
    > I have several routines which are used millions of times in my
    > programs, using the Gnu multi-precision software's floating-point reals
    > (see <http://www.swox.se/gmp>). These are of type mpf_t, and I must
    > explicitly initialize (and later free) all temporary variables of this
    > type.
    >
    > So I hit on the idea of something like this:
    >
    > static int firstcall = 1;
    > mpf_t temp;
    >
    > if (firstcall) {
    > firstcall = 0;
    > mpf_init(temp);
    > }
    > else blahblah
    >
    > First time through, firstcall is 1, so temp gets initialized. Second
    > (and later) times through, temp is already initialized (with what
    > values I don't care, because i'll reset them) and doesn't get
    > REinitialized (which would be a fatal error).
    >
    > It passes -Wall, and it seems to work. Is it legal? Is there anything
    > I need to look out for?


    It's fine *if* temp has static storage duration,
    which it will have if it's declared `static' or if it's
    defined at file scope, outside any function.

    If temp is an `auto' variable, it gets created when
    control enters its block (often a function) and destroyed
    when the block exits. Such a variable will *not* retain
    its value -- including its initialized or non-initialized
    status -- across different invocations of the function.

    --
    Eric Sosman, Jun 12, 2006
    #4
  5. Ronald Bruck

    Al Balmer Guest

    On Mon, 12 Jun 2006 17:59:16 +0000 (UTC), -cnrc.gc.ca
    (Walter Roberson) wrote:

    >In article <120620061031319493%>,
    >Ronald Bruck <> wrote:
    >
    >>So I hit on the idea of something like this:

    >
    >> static int firstcall = 1;
    >> mpf_t temp;

    >
    >> if (firstcall) {
    >> firstcall = 0;
    >> mpf_init(temp);
    >> }
    >> else blahblah

    >
    >>First time through, firstcall is 1, so temp gets initialized. Second
    >>(and later) times through, temp is already initialized (with what
    >>values I don't care, because i'll reset them) and doesn't get
    >>REinitialized (which would be a fatal error).

    >
    >>It passes -Wall, and it seems to work. Is it legal? Is there anything
    >>I need to look out for?

    >
    >Yes, that is legal.
    >
    >You could also save an assignment by reversing the sense of the flag
    >(statics are automatically initialized to 0). If you did that, though,
    >your if would have to be against !flagname and whether that generated
    >more instructions than just testing flagname without the logical
    >negation would be dependant on the optimizer.


    In fact, I usually write

    static int initialized = 0;
    .
    .

    if (!initialized)
    ...

    not because it might save a cycle one time, but because it expresses
    my intention more clearly. IMO.

    --
    Al Balmer
    Sun City, AZ
    Al Balmer, Jun 12, 2006
    #5
  6. Ronald Bruck

    Mark Odell Guest

    Al Balmer wrote:
    > On Mon, 12 Jun 2006 17:59:16 +0000 (UTC), -cnrc.gc.ca
    > (Walter Roberson) wrote:
    >
    > >In article <120620061031319493%>,
    > >Ronald Bruck <> wrote:
    > >
    > >>So I hit on the idea of something like this:

    > >
    > >> static int firstcall = 1;
    > >> mpf_t temp;

    > >
    > >> if (firstcall) {
    > >> firstcall = 0;
    > >> mpf_init(temp);
    > >> }
    > >> else blahblah

    > >
    > >>First time through, firstcall is 1, so temp gets initialized. Second
    > >>(and later) times through, temp is already initialized (with what
    > >>values I don't care, because i'll reset them) and doesn't get
    > >>REinitialized (which would be a fatal error).

    > >
    > >>It passes -Wall, and it seems to work. Is it legal? Is there anything
    > >>I need to look out for?

    > >
    > >Yes, that is legal.
    > >
    > >You could also save an assignment by reversing the sense of the flag
    > >(statics are automatically initialized to 0). If you did that, though,
    > >your if would have to be against !flagname and whether that generated
    > >more instructions than just testing flagname without the logical
    > >negation would be dependant on the optimizer.

    >
    > In fact, I usually write
    >
    > static int initialized = 0;
    > .
    > .
    >
    > if (!initialized)
    > ...
    >
    > not because it might save a cycle one time, but because it expresses
    > my intention more clearly. IMO.


    However, in embedded land, we often discourage this assignment because:
    1) it's redundant and 2) usually adds to the size of the executable
    image that we are trying to cram into Flash (e.g. it gets moved from
    ..bss into the .data section).
    --
    - Mark
    Mark Odell, Jun 12, 2006
    #6
  7. Ronald Bruck

    Michael Mair Guest

    Ronald Bruck schrieb:
    > I have several routines which are used millions of times in my
    > programs, using the Gnu multi-precision software's floating-point reals
    > (see <http://www.swox.se/gmp>). These are of type mpf_t, and I must
    > explicitly initialize (and later free) all temporary variables of this
    > type.
    >
    > So I hit on the idea of something like this:
    >
    > static int firstcall = 1;
    > mpf_t temp;
    >
    > if (firstcall) {
    > firstcall = 0;
    > mpf_init(temp);
    > }
    > else blahblah
    >
    > First time through, firstcall is 1, so temp gets initialized. Second
    > (and later) times through, temp is already initialized (with what
    > values I don't care, because i'll reset them) and doesn't get
    > REinitialized (which would be a fatal error).
    >
    > It passes -Wall, and it seems to work. Is it legal? Is there anything
    > I need to look out for?


    Yes: For this to work as intended,
    1) temp must have static storage duration
    2) temp is not read from before it is assigned some kind of value
    3) the function containing the above (say foo) is allowed to be
    non-reentrant

    The latter may be the one which gives you a heavy headache:
    Essentially, this means that foo() must not recursively call itself
    and you have to be careful in an environment where there may be
    more than one "instance" of the function at work at the same time
    (i.e. using foo() in a shared library of some kind is not possible,
    working on several processors is not possible, ...)


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Jun 12, 2006
    #7
  8. "Mark Odell" <> writes:
    > Al Balmer wrote:

    [...]
    >> In fact, I usually write
    >>
    >> static int initialized = 0;
    >> .
    >> .
    >>
    >> if (!initialized)
    >> ...
    >>
    >> not because it might save a cycle one time, but because it expresses
    >> my intention more clearly. IMO.

    >
    > However, in embedded land, we often discourage this assignment because:
    > 1) it's redundant and 2) usually adds to the size of the executable
    > image that we are trying to cram into Flash (e.g. it gets moved from
    > .bss into the .data section).


    I'd expect a decent optimiziing compiler to generate the same code for
    static int initialized = 0;
    and
    static int initialized;
    Do compilers for embedded systems commonly fail to do this?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Jun 12, 2006
    #8
  9. In article <>,
    Keith Thompson <> wrote:
    >I'd expect a decent optimiziing compiler to generate the same code for
    > static int initialized = 0;
    >and
    > static int initialized;
    >Do compilers for embedded systems commonly fail to do this?


    I believe that some of the [decent] hosted compilers I have used within
    the last decade have generated different code for the two cases.
    It wasn't important to me at the time, so I did not pay attention
    to whether the behaviour changed in later versions.
    --
    Prototypes are supertypes of their clones. -- maplesoft
    Walter Roberson, Jun 12, 2006
    #9
  10. On Mon, 12 Jun 2006 10:31:31 -0700, Ronald Bruck wrote:

    > I have several routines which are used millions of times in my programs,
    > using the Gnu multi-precision software's floating-point reals (see
    > <http://www.swox.se/gmp>). These are of type mpf_t, and I must explicitly
    > initialize (and later free) all temporary variables of this type.
    >
    > So I hit on the idea of something like this:
    >
    > static int firstcall = 1;
    > mpf_t temp;
    >
    > if (firstcall) {
    > firstcall = 0;
    > mpf_init(temp);
    > }
    > else blahblah
    >
    > First time through, firstcall is 1, so temp gets initialized. Second (and
    > later) times through, temp is already initialized (with what values I
    > don't care, because i'll reset them) and doesn't get REinitialized (which
    > would be a fatal error).
    >
    > It passes -Wall, and it seems to work. Is it legal? Is there anything I
    > need to look out for?


    No, because temp doesn't have static duration. When this function exists
    and you call it again, you can't assume temp is initialized. You'll need
    to make it static as well.

    > Initializing, and then freeing, an mpf_t millions of times is not
    > something I want to do. Especially since it may be thousands of bytes
    > long.
    >
    > I should add, I don't care that I never free temp. The program exits
    > before this would become a problem.
    >


    You should take this up in a GMP newsgroup or mailing list. As far as I
    know, a default compile of GMP will attempt to use alloca() or an
    equivalent allocation device which uses automatic storage. This can be
    significantly faster than malloc(), but also means that even if you
    declare temp as static it still won't be initialized next time you enter
    the function. But I'm no expert, and you should follow up on this issue.

    - Bill
    William Ahern, Jun 12, 2006
    #10
  11. Ronald Bruck

    Ronald Bruck Guest

    In article <1150137135.930699@news1nwk>, Eric Sosman
    <> wrote:

    > Ronald Bruck wrote On 06/12/06 13:31,:
    > > I have several routines which are used millions of times in my
    > > programs, using the Gnu multi-precision software's floating-point reals
    > > (see <http://www.swox.se/gmp>). These are of type mpf_t, and I must
    > > explicitly initialize (and later free) all temporary variables of this
    > > type.
    > >
    > > So I hit on the idea of something like this:
    > >
    > > static int firstcall = 1;
    > > mpf_t temp;
    > >
    > > if (firstcall) {
    > > firstcall = 0;
    > > mpf_init(temp);
    > > }
    > > else blahblah
    > >
    > > First time through, firstcall is 1, so temp gets initialized. Second
    > > (and later) times through, temp is already initialized (with what
    > > values I don't care, because i'll reset them) and doesn't get
    > > REinitialized (which would be a fatal error).
    > >
    > > It passes -Wall, and it seems to work. Is it legal? Is there anything
    > > I need to look out for?

    >
    > It's fine *if* temp has static storage duration,
    > which it will have if it's declared `static' or if it's
    > defined at file scope, outside any function.
    >
    > If temp is an `auto' variable, it gets created when
    > control enters its block (often a function) and destroyed
    > when the block exits. Such a variable will *not* retain
    > its value -- including its initialized or non-initialized
    > status -- across different invocations of the function.


    Actually, temp is an "mpf_t", which as I understand the GMP
    documentation is just a pointer to a structure. The GMP itself
    maintains all the created objects (their creation, destruction,
    manipulation) at the outermost scope of the program.

    One potential problem with this method is that the precision of an mpf_t
    might need to change, depending on what calls the function. Example:
    the function takes an array of mpf_t's and adds them. To do that you
    need a temporary variable, as in

    temp := 0.0;
    for (i = 0; i < n; i++) temp += a;

    (you can't really add mpf_t's this way; you have to use specialized
    functions, such as mpf_add(target, firstop, secondop)). But for this
    to work, temp must have at least the precision of the a.

    But that's not a concern in the routines where I use the technique.
    Also, you have to be a little more careful than I showed; an
    "mpf_init(temp)" should be followed by checking code that it really was
    created.

    Glad to hear it's legal, BTW! Thanks to everybody who answered.

    --
    Ron Bruck

    Posted Via Usenet.com Premium Usenet Newsgroup Services
    ----------------------------------------------------------
    ** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
    ----------------------------------------------------------
    http://www.usenet.com
    Ronald Bruck, Jun 13, 2006
    #11
  12. Ronald Bruck

    Eric Sosman Guest

    Ronald Bruck wrote:
    > In article <1150137135.930699@news1nwk>, Eric Sosman
    > <> wrote:
    >
    >
    >>Ronald Bruck wrote On 06/12/06 13:31,:
    >>>
    >>>So I hit on the idea of something like this:
    >>>
    >>> static int firstcall = 1;
    >>> mpf_t temp;
    >>>
    >>> if (firstcall) {
    >>> firstcall = 0;
    >>> mpf_init(temp);
    >>> }
    >>> else blahblah
    >>>

    >>
    >> It's fine *if* temp has static storage duration,
    >>which it will have if it's declared `static' or if it's
    >>defined at file scope, outside any function.
    >>
    >> If temp is an `auto' variable, it gets created when
    >>control enters its block (often a function) and destroyed
    >>when the block exits. Such a variable will *not* retain
    >>its value -- including its initialized or non-initialized
    >>status -- across different invocations of the function.

    >
    > Actually, temp is an "mpf_t", which as I understand the GMP
    > documentation is just a pointer to a structure. The GMP itself
    > maintains all the created objects (their creation, destruction,
    > manipulation) at the outermost scope of the program.


    The actual type underlying mpf_t makes no difference: It can
    be an int, a double, a struct, a pointer to a pointer to a pointer
    to a union of twelve different struct types, or anything at all.
    The point is that if it has `auto' duration, it will not survive
    past the return of the function containing it. Whatever goop
    (technical jargon; sorry) mpf_init might store in it on the first
    call will not (reliably) still be there on the second call.

    Write the Super-Secret Safe Combination on a slip of paper,
    and stick it in your pocket. Take your pants off and put them
    through the laundry. Put your cleaned pants back on, and fish
    the fragmented remains of the paper out of your pocket. Can you
    open the safe?

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 13, 2006
    #12
  13. Ronald Bruck

    Michael Mair Guest

    Ronald Bruck schrieb:
    > In article <1150137135.930699@news1nwk>, Eric Sosman
    > <> wrote:
    >>Ronald Bruck wrote On 06/12/06 13:31,:
    >>
    >>>I have several routines which are used millions of times in my
    >>>programs, using the Gnu multi-precision software's floating-point reals
    >>>(see <http://www.swox.se/gmp>). These are of type mpf_t, and I must
    >>>explicitly initialize (and later free) all temporary variables of this
    >>>type.
    >>>
    >>>So I hit on the idea of something like this:
    >>>
    >>> static int firstcall = 1;
    >>> mpf_t temp;
    >>>
    >>> if (firstcall) {
    >>> firstcall = 0;
    >>> mpf_init(temp);
    >>> }
    >>> else blahblah
    >>>
    >>>First time through, firstcall is 1, so temp gets initialized. Second
    >>>(and later) times through, temp is already initialized (with what
    >>>values I don't care, because i'll reset them) and doesn't get
    >>>REinitialized (which would be a fatal error).
    >>>
    >>>It passes -Wall, and it seems to work. Is it legal? Is there anything
    >>>I need to look out for?

    >>
    >> It's fine *if* temp has static storage duration,
    >>which it will have if it's declared `static' or if it's
    >>defined at file scope, outside any function.
    >>
    >> If temp is an `auto' variable, it gets created when
    >>control enters its block (often a function) and destroyed
    >>when the block exits. Such a variable will *not* retain
    >>its value -- including its initialized or non-initialized
    >>status -- across different invocations of the function.

    >

    <snip>
    > Glad to hear it's legal, BTW! Thanks to everybody who answered.


    Only if you use
    static int firstcall = 1;
    static mpf_t temp; /* 1) */

    if (firstcall) {
    firstcall = 0;
    mpf_init(temp);
    }
    else {
    blahblah
    }
    .... /* no use of temp */
    .... /* assign some value to temp 2) */
    .... /* defs and uses of temp */

    and additionally fulfill condition 3) from
    <>. The other conditions
    are illustrated above.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Jun 13, 2006
    #13
  14. Ronald Bruck

    Chris Torek Guest

    [much snippage]
    >> Al Balmer wrote:
    >>> In fact, I usually write
    >>> static int initialized = 0;


    >"Mark Odell" <> writes:
    >> However, in embedded land, we often discourage this assignment because:
    >> 1) it's redundant and 2) usually adds to the size of the executable
    >> image that we are trying to cram into Flash (e.g. it gets moved from
    >> .bss into the .data section).


    In article <>
    Keith Thompson <> wrote:
    >I'd expect a decent optimiziing compiler to generate the same code for
    > static int initialized = 0;
    >and
    > static int initialized;
    >Do compilers for embedded systems commonly fail to do this?


    It is often desired (and/or desirable) to get different behavior
    for the two. The first results in a "patchable" variable, while
    the second saves space (as Mark Odell mentioned). Of course, the
    example above is not great for this, but compare with:

    int force_number_of_zogs = 0; /* patchable */
    ...
    int nzog;
    ...
    if ((nzog = force_number_of_zogs) == 0) {
    nzog = freememsize() / 20; /* 5% of available RAM */
    nzog /= sizeof *zog;
    }
    zogspace = alloc(nzog * sizeof *zog);

    Full run-time configurability of "patchables" is sometimes even
    better, but adds code size and complexity, especially if the "zog"
    data structure is to be used to read the file that contains the
    configuration specifying the number of "zogs". :)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Jun 13, 2006
    #14
  15. Ronald Bruck

    tedu Guest

    Keith Thompson wrote:
    > I'd expect a decent optimiziing compiler to generate the same code for
    > static int initialized = 0;
    > and
    > static int initialized;
    > Do compilers for embedded systems commonly fail to do this?


    somewhat off topic, but the TI code composer compiler (which in other
    respects compiles a language enough like C that users might assume it
    is a C compiler. it is also referred to as a C/C++ compiler in all
    documenation) does not initialize static variables unless it's
    explicitly spelled out. so your second example may have any initial
    value at run time.
    tedu, Jun 13, 2006
    #15
  16. Ronald Bruck

    Ronald Bruck Guest

    In article <>, Michael Mair
    <> wrote:

    > Ronald Bruck schrieb:
    > > In article <1150137135.930699@news1nwk>, Eric Sosman
    > > <> wrote:
    > >>Ronald Bruck wrote On 06/12/06 13:31,:
    > >>
    > >>>I have several routines which are used millions of times in my
    > >>>programs, using the Gnu multi-precision software's floating-point reals
    > >>>(see <http://www.swox.se/gmp>). These are of type mpf_t, and I must
    > >>>explicitly initialize (and later free) all temporary variables of this
    > >>>type.
    > >>>
    > >>>So I hit on the idea of something like this:
    > >>>
    > >>> static int firstcall = 1;
    > >>> mpf_t temp;
    > >>>
    > >>> if (firstcall) {
    > >>> firstcall = 0;
    > >>> mpf_init(temp);
    > >>> }
    > >>> else blahblah
    > >>>
    > >>>First time through, firstcall is 1, so temp gets initialized. Second
    > >>>(and later) times through, temp is already initialized (with what
    > >>>values I don't care, because i'll reset them) and doesn't get
    > >>>REinitialized (which would be a fatal error).
    > >>>
    > >>>It passes -Wall, and it seems to work. Is it legal? Is there anything
    > >>>I need to look out for?
    > >>
    > >> It's fine *if* temp has static storage duration,
    > >>which it will have if it's declared `static' or if it's
    > >>defined at file scope, outside any function.
    > >>
    > >> If temp is an `auto' variable, it gets created when
    > >>control enters its block (often a function) and destroyed
    > >>when the block exits. Such a variable will *not* retain
    > >>its value -- including its initialized or non-initialized
    > >>status -- across different invocations of the function.

    > >

    > <snip>
    > > Glad to hear it's legal, BTW! Thanks to everybody who answered.

    >
    > Only if you use
    > static int firstcall = 1;
    > static mpf_t temp; /* 1) */
    >
    > if (firstcall) {
    > firstcall = 0;
    > mpf_init(temp);
    > }
    > else {
    > blahblah
    > }
    > .... /* no use of temp */
    > .... /* assign some value to temp 2) */
    > .... /* defs and uses of temp */
    >
    > and additionally fulfill condition 3) from
    > <>. The other conditions
    > are illustrated above.


    I wrote the code fragment from memory. Indeed, I **did** declare temp
    to be "static mpf_t" (otherwise of course it wouldn't still point to
    the structure initialized by the gmp).

    As for being reentrant, no, it doesn't come up in my code.

    Sorry to take so long to reply. I was in Paris for a one-month visit
    and had a mini-stroke ("TIA"). Lost the use of my left index finger
    and thumb, and had to REAL QUICK fly back to LA. (I've recovered most
    of the use, though I still can't type very well.)

    --Ron Bruck
    Ronald Bruck, Jun 15, 2006
    #16
  17. Ronald Bruck

    Old Wolf Guest

    Keith Thompson wrote:
    > I'd expect a decent optimiziing compiler to generate the same code for
    > static int initialized = 0;
    > and
    > static int initialized;
    > Do compilers for embedded systems commonly fail to do this?


    Yes, unfortunately. On one system I develop for, anything with an
    initializer goes into "zerovars" or "initvars", meaning it gets
    initialized, and anything else goes into an uninitialized data area.

    I can't see any positive uses for this; one "advantage" is that if
    the memory is SRAM, then you can restart the application, and
    the value will still have the same value it had before (ie.variables
    of this nature can be used for permanent storage). However this
    is dreadful compared to using an OS facility especially designed
    for storing permanent data.
    Old Wolf, Jun 16, 2006
    #17
  18. Ronald Bruck

    Guest

    Michael Mair wrote:

    > Ronald Bruck schrieb:
    > > I have several routines which are used millions of times in my
    > > programs, using the Gnu multi-precision software's floating-point reals
    > > (see <http://www.swox.se/gmp>). These are of type mpf_t, and I must
    > > explicitly initialize (and later free) all temporary variables of this
    > > type.
    > >
    > > So I hit on the idea of something like this:
    > >
    > > static int firstcall = 1;
    > > mpf_t temp;
    > >
    > > if (firstcall) {
    > > firstcall = 0;
    > > mpf_init(temp);
    > > }
    > > else blahblah
    > >
    > > First time through, firstcall is 1, so temp gets initialized. Second
    > > (and later) times through, temp is already initialized (with what
    > > values I don't care, because i'll reset them) and doesn't get
    > > REinitialized (which would be a fatal error).
    > >
    > > It passes -Wall, and it seems to work. Is it legal? Is there anything
    > > I need to look out for?

    >
    > Yes: For this to work as intended,
    > 1) temp must have static storage duration
    > 2) temp is not read from before it is assigned some kind of value
    > 3) the function containing the above (say foo) is allowed to be
    > non-reentrant
    >
    > The latter may be the one which gives you a heavy headache:
    > Essentially, this means that foo() must not recursively call itself
    > and you have to be careful in an environment where there may be
    > more than one "instance" of the function at work at the same time
    > (i.e. using foo() in a shared library of some kind is not possible,
    > working on several processors is not possible, ...)


    I'm not sure at what level of generality the statements in the last
    paragraph above are meant.

    If for example a function only uses a static variable to decide if it
    is being called for the tirst time plus some variables which get
    initialized the first time the function is called and not modified
    after that , then I don't see anything wrong with the function calling
    itself. Even without these restrictions if there is a way for the
    function to know if it has been called by itself and how many times
    this
    has happened , then things may work just fine. So a function using
    static
    storage may well be constructed in such a way as to allow it to call
    itself.

    I also find the statement about shared libraries confusing. The way I
    understand the term a shared library is one which gets loaded into
    memory
    only once but then can be used by many programmes. Nevertheless the
    variables,
    static or not , of the library functions reside at different parts of
    the
    memory for different programmes so there's no danger of the actions of
    one
    programme affecting the value of function variables when other
    programmes use
    the same function (unless the operating system has a bug of course).

    Finally , whether multiple processors can be used safely or not once
    again depends on the context where copies of the function are to be
    used.
    , Jun 17, 2006
    #18
  19. Ronald Bruck

    Michael Mair Guest

    schrieb:
    > Michael Mair wrote:
    >>Ronald Bruck schrieb:

    <snip>
    >>> static int firstcall = 1;
    >>> mpf_t temp;
    >>>
    >>> if (firstcall) {
    >>> firstcall = 0;
    >>> mpf_init(temp);
    >>> }

    <snip>
    >>>It passes -Wall, and it seems to work. Is it legal? Is there anything
    >>>I need to look out for?

    >>
    >>Yes: For this to work as intended,
    >>1) temp must have static storage duration
    >>2) temp is not read from before it is assigned some kind of value
    >>3) the function containing the above (say foo) is allowed to be
    >> non-reentrant
    >>
    >>The latter may be the one which gives you a heavy headache:
    >>Essentially, this means that foo() must not recursively call itself
    >>and you have to be careful in an environment where there may be
    >>more than one "instance" of the function at work at the same time
    >>(i.e. using foo() in a shared library of some kind is not possible,
    >>working on several processors is not possible, ...)

    >
    > I'm not sure at what level of generality the statements in the last
    > paragraph above are meant.


    This is not meant completely general but a list of examples
    where one _might_ run into problems.

    > If for example a function only uses a static variable to decide if it
    > is being called for the tirst time plus some variables which get
    > initialized the first time the function is called and not modified
    > after that , then I don't see anything wrong with the function calling
    > itself. Even without these restrictions if there is a way for the
    > function to know if it has been called by itself and how many times
    > this has happened , then things may work just fine. So a function
    > using static storage may well be constructed in such a way as to
    > allow it to call itself.


    This is true. However, people sometimes forget that static
    variables must not hold "call instance" specific data if you
    have a call to the function itself between defs and uses as
    the specific data can be changed by the intervening call.
    Originally, I wanted to post a lengthy example pointing out
    various pitfalls about this but had a look at it and threw
    it away -- it neither was "realistic" enough nor short enough.


    > I also find the statement about shared libraries confusing. The way I
    > understand the term a shared library is one which gets loaded into
    > memory
    > only once but then can be used by many programmes. Nevertheless the
    > variables,
    > static or not , of the library functions reside at different parts of
    > the
    > memory for different programmes so there's no danger of the actions of
    > one
    > programme affecting the value of function variables when other
    > programmes use
    > the same function (unless the operating system has a bug of course).


    Actually, "shared library" was too vague on my part.
    What I had in mind when writing this was a ROM library
    storing data to be modified at certain addresses; everyone
    uses the same set of static variables (i.e. executable sharing
    without having a real loader) and different tasks might change
    data during the others were running.
    Simple example:
    unsigned long gimme_unique_id (int new)
    {
    static unsigned long id = 0;
    if (new)
    ++id;
    return id;
    }
    #define NEW_ID() gimme_unique_id(1)
    #define CURR_ID() gimme_unique_id(0)
    Even if the manual says "store NEW_ID() and use it", some
    people still use CURR_ID() to "retrieve" their id. Fun source
    for bugs.


    > Finally , whether multiple processors can be used safely or not once
    > again depends on the context where copies of the function are to be
    > used.


    True.

    I did not want to complicate the thing (in fact, I erased about
    200 lines of text in the original answer to get back to the basic
    stuff); maybe I should have left out the latter examples.


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Jun 17, 2006
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jon

    app vars and cache vars

    Jon, Dec 14, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    384
  2. Tony Cheng
    Replies:
    1
    Views:
    8,187
    Juan T. Llibre
    Feb 24, 2006
  3. Replies:
    1
    Views:
    650
    Jules
    Aug 18, 2005
  4. Linuxguy123
    Replies:
    7
    Views:
    670
    Paddy O'Loughlin
    Feb 20, 2009
  5. caccolangrifata
    Replies:
    18
    Views:
    385
    Chris Torek
    Jul 22, 2011
Loading...

Share This Page