linkage of static and inline functions

Discussion in 'C++' started by Nagrik, Nov 27, 2007.

  1. Nagrik

    Nagrik Guest

    Dear Group,

    The book of Bjarne Stroustrup in chapter 5.4.4 says the following

    "The word static is one of the most overused words in C and C++. For
    static data members it has both of the common meanings: static as in
    "statically allocated" as opposed to on the stack or on the free store
    and static as in "with restricted visibility" as opposed to with
    external linkage. For member functions, static has the second
    meaning."

    In the same book in r.9.4 it says the following:

    "Static members of global class have external linkage (r.3.3). The
    declaration of a static data member in its class declaration is not a
    definition.

    AT r.3.3 it says:

    "A name of file scope that is explicitly declared static is local to
    its translation unit and can be uses as a name for other objects,
    functions, and so on, in other translation units. Such names are said
    to hae internal linkage. A name of file scope that is explicitly
    declared inline is local to its translation unit..."

    /** I am confused about the above mentioned statement (especially of
    the phrase "A name of file scope". Can someone explain this) */

    In the same section it says:

    Static class members have external linkage.

    1. By examining all three statements I am confused about the linkage
    of static member functions as well as inline functions.

    I have the following code

    // File a.h
    #include "stdafx.h"
    #include "iostream.h"

    class A {
    public:
    A() ;
    static void someFn();
    };

    static void indFn();

    //File a.cpp

    #include "stdafx.h"
    #include "a.h"
    A::A() {cout << "Constuctor A"<< endl;}

    void A::someFn() {cout << " print in static" << endl; }

    static void indFn() {cout << " print in static ind" << endl; }

    // File staticcheck.cpp

    #include "stdafx.h"
    #include "iostream.h"
    #include "a.h"

    int main(int argc, char* argv[])
    {
    A* a = new A;
    a->someFn();
    indFn();

    return 0;
    }

    The file staticcheck.cpp only #includes a.h, however, the call to
    function /* a->someFn() */ succeeds, although the definition of the
    function is defined in a.cpp ( Contrary to internal linkage
    directive). At the same time unless I declare and define indFn in a.h
    the call to indFn() does not compile. If I declare the indFn in a.h
    and define in a.cpp the code does not compile. Hence in this case it
    is definitely Internal Linkage.

    2. The inline functions also have internal linkage and it makes sense
    to define them in each and every module. However, later discussions
    give me the impression that compilers now support external linkage for
    inline functions. If this is the case then it should obviate the need
    to define inline function in every module, wherever it is used.

    3. Lastly the static function belongs to the class and not to the
    object. Hence, there is only one copy of the function available for
    all threads to run. Does it mean if one thread is running the static
    function, then that thread will hold a lock on that function and no
    other thread can start running the code of that function unless the
    other thread is done executing the static function.

    4. What happens to local variables (not static variables) declared
    inside static function. Do they retain their updated values across
    multiple threads, or each thread gets to maintain independent values
    for those variables.

    Thanks

    nagrik
     
    Nagrik, Nov 27, 2007
    #1
    1. Advertising

  2. Nagrik wrote:
    > ...
    > The book of Bjarne Stroustrup in chapter 5.4.4 says the following
    >
    > "The word static is one of the most overused words in C and C++. For
    > static data members it has both of the common meanings: static as in
    > "statically allocated" as opposed to on the stack or on the free store
    > and static as in "with restricted visibility" as opposed to with
    > external linkage. For member functions, static has the second
    > meaning."


    You must be used some very outdated version of the book. The meaning of
    'static' for class members (both data member and member functions) is
    completely different from anything in the above quote.

    > In the same book in r.9.4 it says the following:
    >
    > "Static members of global class have external linkage (r.3.3). The
    > declaration of a static data member in its class declaration is not a
    > definition.


    That is correct.

    > AT r.3.3 it says:
    >
    > "A name of file scope that is explicitly declared static is local to
    > its translation unit and can be uses as a name for other objects,
    > functions, and so on, in other translation units. Such names are said
    > to hae internal linkage.


    That is correct, but doesn't apply to class members.

    > A name of file scope that is explicitly
    > declared inline is local to its translation unit..."


    I don't know what "local" stands for here. If it implies "internal
    linkage" then it is incorrect. It used to be that way quite some time
    ago, but not in the standardized C++. Your book must be heavily outdated.

    > /** I am confused about the above mentioned statement (especially of
    > the phrase "A name of file scope". Can someone explain this) */


    Probably "a name declared in file scope".

    > In the same section it says:
    >
    > Static class members have external linkage.


    That's correct.

    > I have the following code
    > // File a.h
    > ...
    > class A {
    > public:
    > A() ;
    > static void someFn();
    > };
    >
    > static void indFn();
    >
    > //File a.cpp
    > ...
    > #include "a.h"
    > A::A() {cout << "Constuctor A"<< endl;}
    >
    > void A::someFn() {cout << " print in static" << endl; }
    >
    > static void indFn() {cout << " print in static ind" << endl; }
    >
    > // File staticcheck.cpp
    > ...
    > #include "a.h"
    >
    > int main(int argc, char* argv[])
    > {
    > A* a = new A;
    > a->someFn();
    > indFn();
    >
    > return 0;
    > }
    >
    > The file staticcheck.cpp only #includes a.h, however, the call to
    > function /* a->someFn() */ succeeds, although the definition of the
    > function is defined in a.cpp ( Contrary to internal linkage
    > directive).


    It should, since 'A::someFn' has external linkage.

    > At the same time unless I declare and define indFn in a.h
    > the call to indFn() does not compile. If I declare the indFn in a.h
    > and define in a.cpp the code does not compile. Hence in this case it
    > is definitely Internal Linkage.


    As expected, since 'indFn' has internal linkage. If you declare and
    define 'indFn' in 'a.h ' the code will compile, but you'll get a
    different instance of 'indFn' in every translation unit.

    > 2. The inline functions also have internal linkage and it makes sense
    > to define them in each and every module.


    No. Inline functions have external linkage by default. Yet, they are
    still required to be defined in every translation unit (where they are
    used directly).

    > However, later discussions
    > give me the impression that compilers now support external linkage for
    > inline functions.


    Yes, they do, since that's what the C++ standard says. However, the only
    thing this basically means is that every inline function will have the
    same address (result of the '&' operator) in every translation unit.

    > If this is the case then it should obviate the need
    > to define inline function in every module, wherever it is used.


    Why? In order to simplify the actual inlining of the calls, the compiler
    wants to see the definition in every translation unit. So, the language
    requires it. This has absolutely nothing to do with linkage, external or
    not. You have to keep in mind that the notion of "external linkage" in
    C++ language is different from what is normally meant under this term in
    some generic language-independent linker.

    > 3. Lastly the static function belongs to the class and not to the
    > object. Hence, there is only one copy of the function available for
    > all threads to run. Does it mean if one thread is running the static
    > function, then that thread will hold a lock on that function and no
    > other thread can start running the code of that function unless the
    > other thread is done executing the static function.


    C++ has no concept of thread, lock, etc. Yet, no. There's no need to
    lock anything in this case.

    > 4. What happens to local variables (not static variables) declared
    > inside static function. Do they retain their updated values across
    > multiple threads, or each thread gets to maintain independent values
    > for those variables.


    Once again, see 3. Yet, no, automatic variables don't retain anything.
    Neither between calls not between threads. Why would they?

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Nov 27, 2007
    #2
    1. Advertising

  3. Nagrik

    nagrik Guest

    On Nov 27, 12:21 pm, Andrey Tarasevich <>
    wrote:
    > Nagrik wrote:
    > > ...
    > > The book of Bjarne Stroustrup in chapter 5.4.4 says the following

    >
    > > "The word static is one of the most overused words in C and C++. For
    > > static data members it has both of the common meanings: static as in
    > > "statically allocated" as opposed to on the stack or on the free store
    > > and static as in "with restricted visibility" as opposed to with
    > > external linkage. For member functions, static has the second
    > > meaning."

    >
    > You must be used some very outdated version of the book. The meaning of
    > 'static' for class members (both data member and member functions) is
    > completely different from anything in the above quote.
    >
    > > In the same book in r.9.4 it says the following:

    >
    > > "Static members of global class have external linkage (r.3.3). The
    > > declaration of a static data member in its class declaration is not a
    > > definition.

    >
    > That is correct.
    >
    > > AT r.3.3 it says:

    >
    > > "A name of file scope that is explicitly declared static is local to
    > > its translation unit and can be uses as a name for other objects,
    > > functions, and so on, in other translation units. Such names are said
    > > to hae internal linkage.

    >
    > That is correct, but doesn't apply to class members.
    >
    > > A name of file scope that is explicitly
    > > declared inline is local to its translation unit..."

    >
    > I don't know what "local" stands for here. If it implies "internal
    > linkage" then it is incorrect. It used to be that way quite some time
    > ago, but not in the standardized C++. Your book must be heavily outdated.
    >
    > > /** I am confused about the above mentioned statement (especially of
    > > the phrase "A name of file scope". Can someone explain this) */

    >
    > Probably "a name declared in file scope".
    >
    > > In the same section it says:

    >
    > > Static class members have external linkage.

    >
    > That's correct.
    >
    >
    >
    >
    >
    > > I have the following code
    > > // File a.h
    > > ...
    > > class A {
    > > public:
    > > A() ;
    > > static void someFn();
    > > };

    >
    > > static void indFn();

    >
    > > //File a.cpp
    > > ...
    > > #include "a.h"
    > > A::A() {cout << "Constuctor A"<< endl;}

    >
    > > void A::someFn() {cout << " print in static" << endl; }

    >
    > > static void indFn() {cout << " print in static ind" << endl; }

    >
    > > // File staticcheck.cpp
    > > ...
    > > #include "a.h"

    >
    > > int main(int argc, char* argv[])
    > > {
    > > A* a = new A;
    > > a->someFn();
    > > indFn();

    >
    > > return 0;
    > > }

    >
    > > The file staticcheck.cpp only #includes a.h, however, the call to
    > > function /* a->someFn() */ succeeds, although the definition of the
    > > function is defined in a.cpp ( Contrary to internal linkage
    > > directive).

    >
    > It should, since 'A::someFn' has external linkage.
    >
    > > At the same time unless I declare and define indFn in a.h
    > > the call to indFn() does not compile. If I declare the indFn in a.h
    > > and define in a.cpp the code does not compile. Hence in this case it
    > > is definitely Internal Linkage.

    >
    > As expected, since 'indFn' has internal linkage. If you declare and
    > define 'indFn' in 'a.h ' the code will compile, but you'll get a
    > different instance of 'indFn' in every translation unit.
    >
    > > 2. The inline functions also have internal linkage and it makes sense
    > > to define them in each and every module.

    >
    > No. Inline functions have external linkage by default. Yet, they are
    > still required to be defined in every translation unit (where they are
    > used directly).
    >
    > > However, later discussions
    > > give me the impression that compilers now support external linkage for
    > > inline functions.

    >
    > Yes, they do, since that's what the C++ standard says. However, the only
    > thing this basically means is that every inline function will have the
    > same address (result of the '&' operator) in every translation unit.
    >
    > > If this is the case then it should obviate the need
    > > to define inline function in every module, wherever it is used.

    >
    > Why? In order to simplify the actual inlining of the calls, the compiler
    > wants to see the definition in every translation unit. So, the language
    > requires it. This has absolutely nothing to do with linkage, external or
    > not. You have to keep in mind that the notion of "external linkage" in
    > C++ language is different from what is normally meant under this term in
    > some generic language-independent linker.
    >
    > > 3. Lastly the static function belongs to the class and not to the
    > > object. Hence, there is only one copy of the function available for
    > > all threads to run. Does it mean if one thread is running the static
    > > function, then that thread will hold a lock on that function and no
    > > other thread can start running the code of that function unless the
    > > other thread is done executing the static function.

    >
    > C++ has no concept of thread, lock, etc. Yet, no. There's no need to
    > lock anything in this case.
    >
    > > 4. What happens to local variables (not static variables) declared
    > > inside static function. Do they retain their updated values across
    > > multiple threads, or each thread gets to maintain independent values
    > > for those variables.

    >
    > Once again, see 3. Yet, no, automatic variables don't retain anything.
    > Neither between calls not between threads. Why would they?
    >
    > --
    > Best regards,
    > Andrey Tarasevich- Hide quoted text -
    >
    > - Show quoted text -


    Andrey,

    Only one clarification though.

    From your reply I follow;

    1. Static member functions inside a class have external linkage. And
    will have single copy of
    code.

    2. Static global functinos (not belonging to any
    class) have internal linkage and will have multiple
    copies of codes with different addresses in an
    application.

    Thanks

    nagrik
     
    nagrik, Nov 27, 2007
    #3
  4. 1. Not sure what is the question here.
    The static member of a class has external linkage (9.4)
    In your example it is A::someFn
    the static function (which is a not a member of any class ) has an
    internal linkage (3.3)

    you have a forward declaration of 'indFn' in a.h and the definition of
    'indFn' in a.cpp.
    But since it is declared status it has internal linkage and visible
    only inside the translation(or compilation) unit. (It is legal to
    define 'indFn' also in staticcheck.cpp).

    3. >the static function belongs to the class and not to the object.
    Correct. Meaning, you can call the function on class, not on the
    instance
    >Hence, there is only one copy of the function available for all threads to run.

    Not sure what do you mean. The CODE segment is always shared for all
    threads.
    The static function, as any other function, can be called from several
    threads simultaneously.

    4. While threads share code segment, data segment and heap, each
    thread has its own stack.
    That's why local variable never require synchronization, only global/
    static data can be accessed from several threads simultaneously.
    >What happens to local variables (not static variables) declared inside static function.

    They are not preserved between calls (not from the same thread, nor
    from different ones)

    HTH
     
    Yakov Gerlovin, Nov 27, 2007
    #4
  5. nagrik wrote:
    > ...
    > From your reply I follow;
    >
    > 1. Static member functions inside a class have external linkage. And
    > will have single copy of
    > code.


    Yes.

    > 2. Static global functinos (not belonging to any
    > class) have internal linkage


    Yes.

    > and will have multiple
    > copies of codes with different addresses in an
    > application.


    Well they _may_ have multiple copies. They _will_ have multiple copies
    if you take explicit steps to create these copies. Like put the
    function's definition into the header file and include it into several
    translation units. Or manually copy the definition of the function into
    several translation units.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Nov 28, 2007
    #5
  6. Nagrik

    James Kanze Guest

    On Nov 27, 8:43 pm, Nagrik <> wrote:
    > The book of Bjarne Stroustrup in chapter 5.4.4 says the following


    It would be interesting to know which version. Several things
    suggest that you might be using an outdated version.

    > "The word static is one of the most overused words in C and
    > C++. For static data members it has both of the common
    > meanings: static as in "statically allocated" as opposed to on
    > the stack or on the free store and static as in "with
    > restricted visibility" as opposed to with external linkage.
    > For member functions, static has the second meaning."


    Note here that he's trying to explain the situation in very
    everyday language (and doing a pretty good job of it, IMHO).
    This is not the language of the standard.

    The restricted visibility he's talking about here is the class;
    class members are not visible outside the scope of the class. A
    static class member is exactly like a free function, except that
    it has restricted visibility, and it has access to private
    members of the class.

    > In the same book in r.9.4 it says the following:


    > "Static members of global class have external linkage (r.3.3).
    > The declaration of a static data member in its class
    > declaration is not a definition.


    This is more formal, and corresponds to the actual language in
    the standard.

    > AT r.3.3 it says:


    > "A name of file scope that is explicitly declared static is local to
    > its translation unit and can be uses as a name for other objects,
    > functions, and so on, in other translation units. Such names are said
    > to hae internal linkage. A name of file scope that is explicitly
    > declared inline is local to its translation unit..."


    And this makes me think you're using an outdated copy: "file
    scope" was removed from C++ when namespaces were introduced.
    Replace "file scope" with "namespace scope" in the above.

    > /** I am confused about the above mentioned statement
    > (especially of the phrase "A name of file scope". Can
    > someone explain this) */


    There are a number of different types of scopes in C++. The
    most important ones are namespace scope, block (or local) scope
    and class scope. If the name is declared outside of any
    function or class, it has namespace scope (and in an earlier
    time, before namespaces, it had file scope).

    By default, a name declared in namespace scope has external
    linkage---the same name, declared in the same scope, in a
    different translation unit, refers to the same entity. If the
    declaration contains the keyword static, then the name has
    internal linkage: other declarations of the name in the same
    scope and in the same translation unit refer to the same entity,
    but declarations in other translation units don't.

    > In the same section it says:


    > Static class members have external linkage.


    Yes. In fact, all class members have external linkage.

    > 1. By examining all three statements I am confused about the
    > linkage of static member functions as well as inline
    > functions.


    > I have the following code


    > // File a.h
    > #include "stdafx.h"
    > #include "iostream.h"


    > class A {
    > public:
    > A() ;
    > static void someFn();
    > };


    > static void indFn();


    Attention. This function has internal linkage. It is very,
    very rare to declare anything with internal linkage in a header.
    (The one exception might be constants.)

    > //File a.cpp


    > #include "stdafx.h"
    > #include "a.h"
    > A::A() {cout << "Constuctor A"<< endl;}


    > void A::someFn() {cout << " print in static" << endl; }


    > static void indFn() {cout << " print in static ind" << endl; }


    > // File staticcheck.cpp


    > #include "stdafx.h"
    > #include "iostream.h"
    > #include "a.h"


    > int main(int argc, char* argv[])
    > {
    > A* a = new A;
    > a->someFn();
    > indFn();


    And this shouldn't compile, because you don't have a definition
    of indFn() (the one in this translation unit, which is not the
    one in a.cpp) anywhere.

    > return 0;
    > }


    > The file staticcheck.cpp only #includes a.h, however, the call to
    > function /* a->someFn() */ succeeds, although the definition of the
    > function is defined in a.cpp ( Contrary to internal linkage
    > directive).


    Class members never have internal linkage. You actually quoted
    a statement which said this for static class members. Class
    members always have external linkage.

    > At the same time unless I declare and define indFn in a.h
    > the call to indFn() does not compile.


    That's because indFn does have internal linkage.

    > If I declare the indFn in a.h and define in a.cpp the code
    > does not compile. Hence in this case it is definitely
    > Internal Linkage.


    > 2. The inline functions also have internal linkage and it
    > makes sense to define them in each and every module. However,
    > later discussions give me the impression that compilers now
    > support external linkage for inline functions. If this is the
    > case then it should obviate the need to define inline function
    > in every module, wherever it is used.


    Inline functions implicitly had internal linkage for the longest
    time (and many compilers didn't support external linkage for
    them). I suspect that this was never desired, but was only due
    to implementation constraints. The techniques necessary to
    implement templates also permitted giving inline functions
    external linkage, and the standard adopted this. Today, inline
    functions behave exactly like any other function in this
    respect (and all reasonably recent compilers support this).

    There is a second issue, however. There is a rule in C++ that
    says that a function, a reference or an object with external
    linkage shall have exactly one definition in the entire program.
    Defining such an entity in more than one translation unit
    results in undefined behavior. There are two major exceptions,
    however: inline functions, and non-exported template entities.
    In these two cases, the standard requires the entity to be
    defined in every translation unit where it is used; it also
    requires that all of the definitions be indentical. This has
    nothing to do with the "linkage", however.

    If you want to see the actual linkage, try taking the address of
    the function. If you define something like:

    inline void someFunc() { }

    in a header, all &someFunc should compare equal, regardless of
    the translation unit. Similarly, if someFunc contains a static
    variable:

    inline int* someFunc() { static int i ; return &i ; }

    the return value must be the same in all translation units.

    If instead you wrote:

    inline static int* someFunc() { static int i ; return &i ; }

    Then the return value and the address of the function must be
    different in every translation unit.

    > 3. Lastly the static function belongs to the class and not to the
    > object. Hence, there is only one copy of the function available for
    > all threads to run. Does it mean if one thread is running the static
    > function, then that thread will hold a lock on that function and no
    > other thread can start running the code of that function unless the
    > other thread is done executing the static function.


    Functions don't have locks. And the current C++ standard
    assumes a single threaded execution model. In practice, of
    course, in a multithreaded environment, there's nothing to
    prevent multiple threads from entering the same function at the
    same time. Regardless of the linkage or scope of the function.

    > 4. What happens to local variables (not static variables) declared
    > inside static function.


    The same as for a non-member function. Each time the function
    is called, a new set of local variables is allocated.

    > Do they retain their updated values across multiple threads,


    What do you mean by that? A function is called from a specific
    thread, and the thread that invocation is executing in doesn't
    change.

    > or each thread gets to maintain independent values for those
    > variables.


    Nothing to do with threads. Each invocation of a function has
    its own instance of the local variables.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 28, 2007
    #6
    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. Daniel Vallstrom
    Replies:
    2
    Views:
    1,898
    Kevin Bracey
    Nov 21, 2003
  2. tropos
    Replies:
    3
    Views:
    466
  3. Martin Wells

    Static inline functions with static local variables

    Martin Wells, Oct 6, 2007, in forum: C Programming
    Replies:
    10
    Views:
    712
    Army1987
    Oct 8, 2007
  4. Replies:
    1
    Views:
    593
    Michael DOUBEZ
    Sep 12, 2008
  5. kid joe

    Inline functions and linkage

    kid joe, May 26, 2009, in forum: C Programming
    Replies:
    5
    Views:
    743
    jameskuyper
    May 27, 2009
Loading...

Share This Page