static keyword

Discussion in 'C Programming' started by eryer, Jan 7, 2010.

  1. eryer

    eryer Guest

    Hi,
    i have a question about static function...for example:

    file1.c
    static void foo(void);
    .....
    void foo ()
    {
    ...
    }

    in this example, optimizations due to static keyword at compiler time
    are performed or not? Or is more correct do something like:

    file1A.c
    static void foo(void);
    .....
    static void foo ()
    {
    ...
    }

    Thanks
    eryer, Jan 7, 2010
    #1
    1. Advertising

  2. eryer

    Ian Collins Guest

    eryer wrote:
    > Hi,
    > i have a question about static function...for example:
    >
    > file1.c
    > static void foo(void);
    > .....
    > void foo ()
    > {
    > ...
    > }
    >
    > in this example, optimizations due to static keyword at compiler time
    > are performed or not?


    Such as? The static keyword simply tells the compiler not to export the
    name; it is only visible in the compilation unit where it is declared.

    > Or is more correct do something like:
    >
    > file1A.c
    > static void foo(void);
    > .....
    > static void foo ()
    > {
    > ...
    > }


    It makes no difference.


    --
    Ian Collins
    Ian Collins, Jan 7, 2010
    #2
    1. Advertising

  3. "eryer" <> wrote in message
    news:...
    > Hi,
    > i have a question about static function...for example:
    >
    > file1.c
    > static void foo(void);
    > .....
    > void foo ()
    > {
    > ...
    > }
    >
    > in this example, optimizations due to static keyword at compiler time
    > are performed or not? Or is more correct do something like:
    >
    > file1A.c
    > static void foo(void);
    > .....
    > static void foo ()
    > {
    > ...
    > }
    >


    IMO, it is better to have both declarations the same, as in the latter case.

    that said, static defines semantics, not optimizations.
    static on a function will essentially just hide it from other compilation
    units, but typically little more than this.
    this is the same semantics as for global variables.


    any optimizations done, or not done, due to the use of static are compiler
    dependent.
    in most cases, there is unlikely to be much of any real difference though...

    granted then, if you mean putting a static in a header, vs a non-static
    function in another compilation unit, this does effect something: it may
    allow the compiler to inline the function (the inline keyword may also serve
    as a hint for it to do so as well, although not all compilers accept the
    'inline' keyword).

    however, in this case, the optimization would be due to the visability of
    the function (it being in the same compilation unit, hence the compiler can
    see its sourse), and not due to 'static', which in this case would serve
    mostly to "hide" the function from other compilation units (such that you
    can put the function in a header without risking the linker making a big
    fuss and possibly refusing to link the program).

    I have observed though that linkers may also silently "merge" all these
    duplicate static functions (from headers), such that they don't take up lots
    of extra space in the compiled output.

    a similar observation is that the compiler may also omit the functions if
    they are never called.


    but, then again, all this is still due to the semantics, of the modifier,
    rather than a result of the modifier itself.

    for example, it is very well possible that a compiler will inline a function
    even though it does not use any extra keywords, ...

    and, it is also very well possible that a compiler will be stupid and not do
    anything differently than simply obey the semantics of the keyword (IOW:
    avoid a link-time error due to multiple-definition).


    > Thanks
    >
    BGB / cr88192, Jan 7, 2010
    #3
  4. eryer

    Nobody Guest

    On Thu, 07 Jan 2010 14:56:42 -0800, eryer wrote:

    > i have a question about static function...for example:
    >
    > file1.c
    > static void foo(void);
    > .....
    > void foo ()
    > {
    > ...
    > }
    >
    > in this example, optimizations due to static keyword at compiler time
    > are performed or not?


    Maybe.

    Declaring the function "static" gives the compiler more scope for
    optimisation, as it can determine exhaustively the contexts in which the
    function may be called.
    Nobody, Jan 10, 2010
    #4
  5. eryer

    Flash Gordon Guest

    Nobody wrote:
    > On Thu, 07 Jan 2010 14:56:42 -0800, eryer wrote:
    >
    >> i have a question about static function...for example:
    >>
    >> file1.c
    >> static void foo(void);
    >> .....
    >> void foo ()
    >> {
    >> ...
    >> }
    >>
    >> in this example, optimizations due to static keyword at compiler time
    >> are performed or not?

    >
    > Maybe.
    >
    > Declaring the function "static" gives the compiler more scope for
    > optimisation, as it can determine exhaustively the contexts in which the
    > function may be called.


    This could allow it to take shortcuts on the calling conventions, it
    might also encourage inlining, especially for a function which is ony
    called once.
    --
    Flash Gordon
    Flash Gordon, Jan 10, 2010
    #5
  6. Flash Gordon wrote:
    > Nobody wrote:
    >> Declaring the function "static" gives the compiler more scope for
    >> optimisation, as it can determine exhaustively the contexts in which the
    >> function may be called.

    >
    > This could allow it to take shortcuts on the calling conventions,


    Interesting. For instance, a compiler for x86 might decide to forgo the
    usual stack-based calling convention and use a register-based one, which
    would be faster (assuming the number of arguments is reasonable). It
    might also allow the compiler to skip saving some registers in the
    calling function if it knows that the called function won't modify them.

    However, does any compiler in the wild actually do this?

    > it might also encourage inlining, especially for a function which is ony
    > called once.


    I suspect that, in general, compilers would either inline or not
    regardless of the static designation.

    I can see one way the heuristics might be affected, though. If the
    called function validates its arguments, and the compiler can prove that
    the validation has already been done (or explicit values set) by every
    calling function, it may end up with a bunch of dead code that can be
    eliminated, which in turn might drop the size below its heuristics'
    threshold for inlining.

    S

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Jan 13, 2010
    #6
  7. eryer

    Eric Sosman Guest

    On 1/12/2010 10:44 PM, Stephen Sprunk wrote:
    > Flash Gordon wrote:
    >> Nobody wrote:
    >>> Declaring the function "static" gives the compiler more scope for
    >>> optimisation, as it can determine exhaustively the contexts in which the
    >>> function may be called.

    >>
    >> This could allow it to take shortcuts on the calling conventions,

    >
    > Interesting. For instance, a compiler for x86 might decide to forgo the
    > usual stack-based calling convention and use a register-based one, which
    > would be faster (assuming the number of arguments is reasonable). It
    > might also allow the compiler to skip saving some registers in the
    > calling function if it knows that the called function won't modify them.
    >
    > However, does any compiler in the wild actually do this?


    Dunno about that specific optimization, but there have
    certainly been compilers that optimized `static' functions
    differently than externally-linked ones. A <ctype.h> header
    I once encountered contained *definitions* of toupper() and
    the rest of the functions, all `static'. The accompanying
    compiler would discard any that weren't used, and would try
    to in-line those that were. This was, oh, fifteen or twenty
    years ago, well before `inline' came into the language. (In
    fact, the header was for the pre-ANSI VAXC compiler.)

    If you formed a function pointer to isdigit(), say, and
    passed it somewhere, the compiler would naturally compile a
    free-standing (but still `static') isdigit() function. This
    raised the possibility that two different translation units
    could form isdigit() pointers that would compare unequal. I
    don't know whether that possibility would violate anything in
    the Standard; there was a discussion maybe twenty-five years
    ago about whether `memcpy == memmove' was permissible, and IIRC
    no satisfactory conclusion was ever reached.

    --
    Eric Sosman
    lid
    Eric Sosman, Jan 13, 2010
    #7
  8. eryer

    Richard Bos Guest

    Eric Sosman <> wrote:

    > the Standard; there was a discussion maybe twenty-five years
    > ago about whether `memcpy == memmove' was permissible, and IIRC
    > no satisfactory conclusion was ever reached.


    I can't see a reason why not.

    Behaviour isn't a reason. memmove() has stricter requirements than
    memcpy(), but in the cases where they differ, memcpy() has undefined
    behaviour. If the outcome of that undefined behaviour happens to be
    "behaves as if it were memmove()", that is certainly required.

    Address _could_ be a reason, but I cannot find anything in the Standard
    which demands that different functions have addresses that compare
    differently. Nor, for that matter, can I find an explicit, blanket
    demand that all objects' addresses must differ.
    The difference between these cases is, of course, that objects can be
    assigned to, and functions can be called. If you assign a value to one
    object through a pointer, and that changes another object behind your
    back, a conforming program will be able to notice. Therefore, assigning
    to one object's address must not change what is at another object's; and
    therefore, objects' addresses must be distinguishable.
    Functions, though, are different. You can't assign to them; you can only
    call them. When the only difference between two functions occurs when
    there is undefined or implementation-defined behaviour, there is no
    guarantee that any strictly conforming program can detect the difference
    at all.
    There is a parallel, by the way, in a specific type of object: string
    literals. No strictly conforming program can assign a value to a string
    literal; implementations can, and do, take advantage of this by merging
    (partly) equal string literals, making their addresses identical or
    making the address of one fall inside the other.

    Put most illustratively, I would say that memmove == memcpy is
    permissible for the same reason that "bcde" == "abcde"+1 is.

    Richard
    Richard Bos, Jan 13, 2010
    #8
  9. eryer

    Eric Sosman Guest

    On 1/13/2010 4:38 PM, Richard Bos wrote:
    > Eric Sosman<> wrote:
    >
    >> the Standard; there was a discussion maybe twenty-five years
    >> ago about whether `memcpy == memmove' was permissible, and IIRC
    >> no satisfactory conclusion was ever reached.

    >
    > I can't see a reason why not.
    >
    > Behaviour isn't a reason. memmove() has stricter requirements than
    > memcpy(), but in the cases where they differ, memcpy() has undefined
    > behaviour. If the outcome of that undefined behaviour happens to be
    > "behaves as if it were memmove()", that is certainly required.
    >[...]


    That's the gist of the argument as I recall it. Others
    didn't buy it, and the discussion raged back and forth for no
    few exchanges before sort of petering out. Early-to-middle
    1990's, IIRC, should anyone want to excavate the ruins.

    --
    Eric Sosman
    lid
    Eric Sosman, Jan 13, 2010
    #9
  10. eryer

    Guest

    Richard Bos <> wrote:
    >
    > Address _could_ be a reason, but I cannot find anything in the Standard
    > which demands that different functions have addresses that compare
    > differently. Nor, for that matter, can I find an explicit, blanket
    > demand that all objects' addresses must differ.


    6.5.9p6:

    Two pointers compare equal if and only if both are null
    pointers, both are pointers to the same object (including a
    pointer to an object and a subobject at its beginning) or
    function...

    Different objects are not "the same object", nor are different functions
    "the same function".
    --
    Larry Jones

    Somebody's always running my life. I never get to do what I want to do.
    -- Calvin
    , Jan 14, 2010
    #10
  11. eryer

    Nobody Guest

    On Tue, 12 Jan 2010 21:44:27 -0600, Stephen Sprunk wrote:

    >>> Declaring the function "static" gives the compiler more scope for
    >>> optimisation, as it can determine exhaustively the contexts in which the
    >>> function may be called.

    >>
    >> This could allow it to take shortcuts on the calling conventions,

    >
    > Interesting. For instance, a compiler for x86 might decide to forgo the
    > usual stack-based calling convention and use a register-based one, which
    > would be faster (assuming the number of arguments is reasonable). It
    > might also allow the compiler to skip saving some registers in the
    > calling function if it knows that the called function won't modify them.
    >
    > However, does any compiler in the wild actually do this?


    Consider the case where the function is inlined more than once, then
    common subexpression elimination moves (most of) the inlined code into a
    separate subroutine. If the function is static, and all calls have been
    inlined, the "real" function definition will be elided.

    The effect is the same as implementing the function with a custom calling
    convention.
    Nobody, Jan 15, 2010
    #11
  12. eryer

    Flash Gordon Guest

    Nobody wrote:
    > On Tue, 12 Jan 2010 21:44:27 -0600, Stephen Sprunk wrote:
    >
    >>>> Declaring the function "static" gives the compiler more scope for
    >>>> optimisation, as it can determine exhaustively the contexts in which the
    >>>> function may be called.
    >>> This could allow it to take shortcuts on the calling conventions,

    >> Interesting. For instance, a compiler for x86 might decide to forgo the
    >> usual stack-based calling convention and use a register-based one, which
    >> would be faster (assuming the number of arguments is reasonable). It
    >> might also allow the compiler to skip saving some registers in the
    >> calling function if it knows that the called function won't modify them.
    >>
    >> However, does any compiler in the wild actually do this?

    >
    > Consider the case where the function is inlined more than once, then
    > common subexpression elimination moves (most of) the inlined code into a
    > separate subroutine. If the function is static, and all calls have been
    > inlined, the "real" function definition will be elided.


    If and only if the function's address is not stored in a pointer (which
    applies to my earlier comments too).

    > The effect is the same as implementing the function with a custom calling
    > convention.


    It can be, but not always.

    One reason you might get different (faster) calling conventions is if
    there is an API which specifies one set of conventions (for flexibility)
    but something else is faster on modern hardware. If the function is
    static and no pointers to it exist, then the compiler knows it is safe
    to use the faster calling conventions.

    A reason a static function might be inlined when a non-static function
    is not is that the balance on code size moves. If it is static and no
    pointer is taken, then if all calls are inlined and the original
    eliminated it has not inflated code size by as much as inlining it *and*
    keeping the original. This is especially relevant if the function is
    only called a small number of times (the extreme case being a function
    called exactly once).

    So I always declare and define functions as static unless I explicitly
    need them to be externally visible. Always give the compiler all the
    information you can, it might help it make the best decision...
    --
    Flash Gordon
    Flash Gordon, Jan 16, 2010
    #12
  13. eryer

    Richard Bos Guest

    wrote:

    > Richard Bos <> wrote:
    > >
    > > Address _could_ be a reason, but I cannot find anything in the Standard
    > > which demands that different functions have addresses that compare
    > > differently. Nor, for that matter, can I find an explicit, blanket
    > > demand that all objects' addresses must differ.

    >
    > 6.5.9p6:
    >
    > Two pointers compare equal if and only if both are null
    > pointers, both are pointers to the same object (including a
    > pointer to an object and a subobject at its beginning) or
    > function...
    >
    > Different objects are not "the same object", nor are different functions
    > "the same function".


    That has not stopped implementation writers from equalising pointers to
    string literals. In the source code, these are definitely different
    objects, but since a program can only discover the difference by
    invoking undefined behaviour, they are allowed to be "the same object"
    for pointer purposes. Unless you're telling us that this _very_ common
    optimisation is illegal, I don't see why the same thing should not be
    allowed for functions for which the same proviso holds.

    Richard
    Richard Bos, Jan 21, 2010
    #13
  14. (Richard Bos) writes:
    > wrote:
    >> Richard Bos <> wrote:
    >> >
    >> > Address _could_ be a reason, but I cannot find anything in the Standard
    >> > which demands that different functions have addresses that compare
    >> > differently. Nor, for that matter, can I find an explicit, blanket
    >> > demand that all objects' addresses must differ.

    >>
    >> 6.5.9p6:
    >>
    >> Two pointers compare equal if and only if both are null
    >> pointers, both are pointers to the same object (including a
    >> pointer to an object and a subobject at its beginning) or
    >> function...
    >>
    >> Different objects are not "the same object", nor are different functions
    >> "the same function".

    >
    > That has not stopped implementation writers from equalising pointers to
    > string literals. In the source code, these are definitely different
    > objects, but since a program can only discover the difference by
    > invoking undefined behaviour, they are allowed to be "the same object"
    > for pointer purposes. Unless you're telling us that this _very_ common
    > optimisation is illegal, I don't see why the same thing should not be
    > allowed for functions for which the same proviso holds.


    There are no objects in my source code; objects exist only during
    program execution.

    The object in question is the "array of static storage duration"
    mentioned in C99 6.4.5p5. The standard explicitly allows two string
    literals to refer to the same object in C99 6.4.5p6:

    It is unspecified whether these arrays are distinct provided their
    elements have the appropriate values. If the program attempts to
    modify such an array, the behavior is undefined.

    As for memcpy and memmove possibly having the same address, I can
    imagine a program storing the address of a standard function and later
    making some decision based on which standard function the address
    points to. I have difficulty imagining *good* code doing something
    like this, but it isn't the standard's job to impose good coding
    practices.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 21, 2010
    #14
    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. =?Utf-8?B?RGF2ZQ==?=

    Static keyword usage in asp.net?

    =?Utf-8?B?RGF2ZQ==?=, Nov 18, 2005, in forum: ASP .Net
    Replies:
    11
    Views:
    5,463
    =?Utf-8?B?RGF2ZQ==?=
    Nov 29, 2005
  2. Matt
    Replies:
    3
    Views:
    1,102
    aatishp
    Mar 15, 2012
  3. cppaddict
    Replies:
    2
    Views:
    350
    cppaddict
    May 2, 2004
  4. Replies:
    6
    Views:
    439
    Peter Otten
    May 10, 2007
  5. Hamilton, William

    RE: keyword checker - keyword.kwlist

    Hamilton, William, May 10, 2007, in forum: Python
    Replies:
    4
    Views:
    340
Loading...

Share This Page