Local scope, external linkage?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Peter Ammon

    #1

    Local scope, external linkage?

    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
  • Jeremy Yallop

    #2
    Re: Local scope, external linkage?

    Peter Ammon wrote:[color=blue]
    > 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.[/color]

    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.

    Comment

    • Eric Sosman

      #3
      Re: Local scope, external linkage?

      Peter Ammon wrote:[color=blue]
      > 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;
      > }[/color]

      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@sun .com

      Comment

      • CBFalconer

        #4
        Re: Local scope, external linkage?

        Peter Ammon wrote:[color=blue]
        >
        > 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?[/color]

        I think the closest you can come is:

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

        /* File1.c */
        #include "File1.h"
        static foo foovalue;
        foo *fooptrgetter(v oid) {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 (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
        Available for consulting/temporary embedded and systems.
        <http://cbfalconer.home .att.net> USE worldnet address!

        Comment

        • Alex Fraser

          #5
          Re: Local scope, external linkage?

          "CBFalconer " <cbfalconer@yah oo.com> wrote in message
          news:40DA1E2B.5 CB3B3D3@yahoo.c om...[color=blue]
          > Peter Ammon wrote:[color=green]
          > > I would like to share a variable between two functions defined in two
          > > separate source files; no other functions will need the global variable[/color][/color]
          [snip][color=blue]
          > I think the closest you can come is:
          >
          > /* File1.h */
          > typedef /* whatever */ foo;
          > foo *fooptrgetter(v oid);
          >
          > /* File1.c */
          > #include "File1.h"
          > static foo foovalue;
          > foo *fooptrgetter(v oid) {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.[/color]

          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


          Comment

          Working...