Local scope, external linkage?

Discussion in 'C Programming' started by Peter Ammon, Jun 23, 2004.

  1. Peter Ammon

    Peter Ammon Guest

    I would like to share a variable between two functions defined in two
    separate source files; no other functions will need the global variable
    so I'd prefer to not give it file scope. Thus, I want a variable with
    local scope, external linkage, and static storage.

    I believe I can do this for the file that does not define the variable
    by declaring it inside a function. Can I also avoid giving it file
    scope in the file that does define the variable?

    /* File 1 */

    void function1(void) {
    /* How do I make myGlobal have static storage,
    * and external linkage?
    */
    int myGlobal;
    }

    /* File 2 */

    void function2(void) {
    /* This does what I think it does, right? */
    extern int myGlobal;
    }

    Thanks for your help,
    -Peter
    Peter Ammon, Jun 23, 2004
    #1
    1. Advertising

  2. Peter Ammon wrote:
    > I would like to share a variable between two functions defined in two
    > separate source files; no other functions will need the global variable
    > so I'd prefer to not give it file scope. Thus, I want a variable with
    > local scope, external linkage, and static storage.


    You can't have one, I'm afraid.

    If an identifier declared with external linkage is used in an
    expression (other than as part of the operand of a sizeof operator
    whose result is an integer constant), somewhere in the entire program
    there shall be exactly one external definition for the identifier;
    [C99 6.9]

    External definitions always appear at file scope:

    An external definition is an external declaration that is also a
    definition of a function (other than an inline definition) or an
    object.

    translation-unit:
    external-declaration
    translation-unit external-declaration

    About the closest you can get to what you want, I think, is to define
    the variable in its own source file (or as the last declaration in one
    of the source files in which it is used), and have block-scope
    "extern" declarations (as in your example of function2()) in both the
    functions that use the variable; this effectively limits scope to the
    regions where the identifier is used. Since the same variable is
    referenced in two separate translation units, the linkage must be the
    maximum possible (i.e. "external").

    Jeremy.
    Jeremy Yallop, Jun 23, 2004
    #2
    1. Advertising

  3. Peter Ammon

    Eric Sosman Guest

    Peter Ammon wrote:
    > I would like to share a variable between two functions defined in two
    > separate source files; no other functions will need the global variable
    > so I'd prefer to not give it file scope. Thus, I want a variable with
    > local scope, external linkage, and static storage.
    >
    > I believe I can do this for the file that does not define the variable
    > by declaring it inside a function. Can I also avoid giving it file
    > scope in the file that does define the variable?
    >
    > /* File 1 */
    >
    > void function1(void) {
    > /* How do I make myGlobal have static storage,
    > * and external linkage?
    > */
    > int myGlobal;
    > }
    >
    > /* File 2 */
    >
    > void function2(void) {
    > /* This does what I think it does, right? */
    > extern int myGlobal;
    > }


    C's linkage scheme is not fancy enough to do what
    you desire. All identifiers with external linkage are
    (potentially) visible to all parts of the program, and
    there's no notion of a "package-private" linkage.

    In the code you've shown, the identifier `myGlobal'
    refers to two different objects:

    - In function1(), it refers to an `auto' variable.
    The identifier has no linkage, neither external
    nor internal. You could change the storage class
    by adding the `static' or `register' (or even
    `typedef'!) keyword, but it wouldn't alter the
    fact that this `myGlobal' has nothing at all to
    do with any other `myGlobal' identifier that might
    be lying around in your program.

    - In function2(), `myGlobal' has external linkage.
    When the various translation units are combined
    into a program, this `myGlobal' and any others
    that also have external linkage will be made to
    refer to one object. Exactly one translation unit
    must provide an actual definition of the object,
    at file scope and without the `static' keyword --
    and if that definition is a function or is a data
    object that isn't `int', you've got trouble.

    "You can't always get what you want." -- J&R

    --
    Eric Sosman, Jun 23, 2004
    #3
  4. Peter Ammon

    CBFalconer Guest

    Peter Ammon wrote:
    >
    > I would like to share a variable between two functions defined in two
    > separate source files; no other functions will need the global variable
    > so I'd prefer to not give it file scope. Thus, I want a variable with
    > local scope, external linkage, and static storage.
    >
    > I believe I can do this for the file that does not define the variable
    > by declaring it inside a function. Can I also avoid giving it file
    > scope in the file that does define the variable?


    I think the closest you can come is:

    /* File1.h */
    typedef /* whatever */ foo;
    foo *fooptrgetter(void);

    /* File1.c */
    #include "File1.h"
    static foo foovalue;
    foo *fooptrgetter(void) {return &foovalue)

    and now any other file can access it by #include "File1.h" and
    getting the pointer as needed.

    If foo is a struct you can ensure readonly access by coding the
    foogetter() function. Modifying foo would then be restricted to
    functions in File1.c, and you can control their use by prototyping
    them in a separate header file. An example of this mechanism
    exposes the statistics from my hashlib package (see download
    section of my site).

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
    CBFalconer, Jun 24, 2004
    #4
  5. Peter Ammon

    Alex Fraser Guest

    "CBFalconer" <> wrote in message
    news:...
    > Peter Ammon wrote:
    > > I would like to share a variable between two functions defined in two
    > > separate source files; no other functions will need the global variable

    [snip]
    > I think the closest you can come is:
    >
    > /* File1.h */
    > typedef /* whatever */ foo;
    > foo *fooptrgetter(void);
    >
    > /* File1.c */
    > #include "File1.h"
    > static foo foovalue;
    > foo *fooptrgetter(void) {return &foovalue)
    >
    > and now any other file can access it by #include "File1.h" and
    > getting the pointer as needed.
    >
    > If foo is a struct you can ensure readonly access by coding the
    > foogetter() function.


    Indeed, this scheme is largely pointless unless you do precisely that,
    otherwise you might as well have the obvious:

    /* File1.h */
    typedef /* whatever */ foo;
    extern foo foovalue;

    /* File1.c */
    #include "File1.h"
    foo foovalue;

    The only effective difference between this and the above is substituting one
    external identifier for another.

    Alex
    Alex Fraser, Jun 24, 2004
    #5
    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. pembed2003

    scope, static and linkage

    pembed2003, May 26, 2004, in forum: C++
    Replies:
    6
    Views:
    522
    pembed2003
    May 27, 2004
  2. pembed2003

    scope and linkage rule, very confusing!

    pembed2003, May 26, 2004, in forum: C Programming
    Replies:
    5
    Views:
    649
    Jack Klein
    May 27, 2004
  3. rick

    scope and linkage

    rick, Mar 31, 2006, in forum: C Programming
    Replies:
    5
    Views:
    350
    Jack Klein
    Apr 1, 2006
  4. Neelesh Bodas
    Replies:
    6
    Views:
    319
    David Harmon
    Jan 4, 2006
  5. Replies:
    1
    Views:
    574
    Michael DOUBEZ
    Sep 12, 2008
Loading...

Share This Page