"extern" meaning

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

    #1

    "extern" meaning

    Hi all,
    I am reading "C: A Reference Manual" 4th ed and I get lost for the
    "extern". It says that global object without specifying the
    storage-class specifier will have "extern" as the default storage-class
    specifier. My (little) C experience tells me that an object with
    "extern" is to let the linker knows that the object is referencing the
    object defined in somewhere, and this "somewhere" object does not have
    the storage-class specifier "extern". That is:
    <------------ file A ------------>
    int A;
    ...
    A=10;
    <------------ file B ------------>
    extern int A;
    if (A)
    ...

    But if the default storage-class specifier is "extern", then
    variable "int A" is, indeed, "extern int A". Then who is the definiting
    occurence?
    Please correct me if there is a mis-concept.

  • Peteris Krumins

    #2
    Re: &quot;extern&qu ot; meaning

    ccwork wrote:[color=blue]
    > Hi all,
    > I am reading "C: A Reference Manual" 4th ed and I get lost for the
    > "extern". It says that global object without specifying the
    > storage-class specifier will have "extern" as the default[/color]
    storage-class[color=blue]
    > specifier. My (little) C experience tells me that an object with
    > "extern" is to let the linker knows that the object is referencing[/color]
    the[color=blue]
    > object defined in somewhere, and this "somewhere" object does not[/color]
    have[color=blue]
    > the storage-class specifier "extern". That is:
    > <------------ file A ------------>
    > int A;
    > ...
    > A=10;
    > <------------ file B ------------>
    > extern int A;
    > if (A)
    > ...
    >
    > But if the default storage-class specifier is "extern", then
    > variable "int A" is, indeed, "extern int A". Then who is the[/color]
    definiting[color=blue]
    > occurence?
    > Please correct me if there is a mis-concept.[/color]

    'extern' specifies external linkage for an identifier, nothing more.
    It makes the identifier known to the linker so it could be referenced.

    The definition of variable A occurs in file "A".



    P.Krumins

    Comment

    • Andrey Tarasevich

      #3
      Re: &quot;extern&qu ot; meaning

      ccwork wrote:[color=blue]
      > I am reading "C: A Reference Manual" 4th ed and I get lost for the
      > "extern". It says that global object without specifying the
      > storage-class specifier will have "extern" as the default storage-class
      > specifier. My (little) C experience tells me that an object with
      > "extern" is to let the linker knows that the object is referencing the
      > object defined in somewhere, and this "somewhere" object does not have
      > the storage-class specifier "extern". That is:
      > <------------ file A ------------>
      > int A;
      > ...
      > A=10;
      > <------------ file B ------------>
      > extern int A;
      > if (A)
      > ...
      >
      > But if the default storage-class specifier is "extern", then
      > variable "int A" is, indeed, "extern int A". Then who is the definiting
      > occurence?
      > Please correct me if there is a mis-concept.[/color]

      C language doesn't not rely on the concept of "linker". There's no
      "linker" in C. At language level, external linkage of an identifier
      means just one thing - that this identifier refers to the same object
      (or function) in all translation units. How this requirement is
      implemented in practice (using that "linker" thingy or something else)
      is an implementation detail, a completely different story, irrelevant to
      the language itself.

      If you really want to think about this in terms of "exporting/importing"
      access to the object, think of it this way: when 'extern' is included in
      a _definition_ of some object, it "exports" the corresponding identifier
      to the outside world (i.e. other translation units), but when 'extern'
      is included in a mere _declaration_ of an object, it "imports" the
      identifier from the outside world.

      In your case 'int A' in file 'A' is a definition of an identifier 'A'
      attached to an object of type 'int'. This identifier has external
      linkage by default, meaning that identifier 'A' is "exported", made
      accessible from other translation units. In order to access this object
      other translation units have to "import" this identifier by providing an
      'extern' _declaration_ for it. That's exactly what you have in file 'B'.

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • Peter Nilsson

        #4
        Re: &quot;extern&qu ot; meaning

        Andrey Tarasevich wrote:[color=blue]
        >
        > C language doesn't not rely on the concept of "linker".[/color]

        [I presume you didn't mean to add the extra 'not'.]
        [color=blue]
        > There's no "linker" in C.[/color]

        So what's translation phase 8 all about then?
        [color=blue]
        > At language level, external linkage of an identifier means just
        > one thing - that this identifier refers to the same object (or
        > function) in all translation units. How this requirement is
        > implemented in practice (using that "linker" thingy or something
        > else) is an implementation detail, a completely different story,
        > irrelevant to the language itself.[/color]

        "Library components are linked..."

        How does an implementation link _without_ a linker?

        Even C interpreters must have a linker, just as they must have
        a function call stack.

        --
        Peter

        Comment

        • ccwork

          #5
          Re: &quot;extern&qu ot; meaning


          Andrey Tarasevich wrote:[color=blue]
          > ccwork wrote:[color=green]
          > > I am reading "C: A Reference Manual" 4th ed and I get lost for[/color][/color]
          the[color=blue][color=green]
          > > "extern". It says that global object without specifying the
          > > storage-class specifier will have "extern" as the default[/color][/color]
          storage-class[color=blue][color=green]
          > > specifier. My (little) C experience tells me that an object with
          > > "extern" is to let the linker knows that the object is referencing[/color][/color]
          the[color=blue][color=green]
          > > object defined in somewhere, and this "somewhere" object does not[/color][/color]
          have[color=blue][color=green]
          > > the storage-class specifier "extern". That is:
          > > <------------ file A ------------>
          > > int A;
          > > ...
          > > A=10;
          > > <------------ file B ------------>
          > > extern int A;
          > > if (A)
          > > ...
          > >
          > > But if the default storage-class specifier is "extern", then
          > > variable "int A" is, indeed, "extern int A". Then who is the[/color][/color]
          definiting[color=blue][color=green]
          > > occurence?
          > > Please correct me if there is a mis-concept.[/color]
          >
          > C language doesn't not rely on the concept of "linker". There's no
          > "linker" in C. At language level, external linkage of an identifier
          > means just one thing - that this identifier refers to the same object
          > (or function) in all translation units. How this requirement is
          > implemented in practice (using that "linker" thingy or something[/color]
          else)[color=blue]
          > is an implementation detail, a completely different story, irrelevant[/color]
          to[color=blue]
          > the language itself.
          >
          > If you really want to think about this in terms of[/color]
          "exporting/importing"[color=blue]
          > access to the object, think of it this way: when 'extern' is included[/color]
          in[color=blue]
          > a _definition_ of some object, it "exports" the corresponding[/color]
          identifier[color=blue]
          > to the outside world (i.e. other translation units), but when[/color]
          'extern'[color=blue]
          > is included in a mere _declaration_ of an object, it "imports" the
          > identifier from the outside world.
          >
          > In your case 'int A' in file 'A' is a definition of an identifier 'A'
          > attached to an object of type 'int'. This identifier has external
          > linkage by default, meaning that identifier 'A' is "exported", made
          > accessible from other translation units. In order to access this[/color]
          object[color=blue]
          > other translation units have to "import" this identifier by providing[/color]
          an[color=blue]
          > 'extern' _declaration_ for it. That's exactly what you have in file[/color]
          'B'.

          That's the problem. Since global variable is regraded as "extern"
          (is this right?), in other words, file A means:
          <------------ file A ------------>
          extern int A;
          ...
          A=10;
          <------------ file B ------------>
          extern int A;
          if (A)
          ...

          Then how do I know which one is the defining occurrence of A? Does
          the assignment on A=10 specify the declaraction "extern int A" in file
          A is the definition? Or else?

          Comment

          • baumann@pan

            #6
            Re: &quot;extern&qu ot; meaning



            if both files have variabled defined as "extern" , there is no harm if
            one is of the form:

            extern int a =1;

            i will try on rh9 to test it.

            Comment

            • Andrey Tarasevich

              #7
              Re: &quot;extern&qu ot; meaning

              ccwork wrote:[color=blue][color=green]
              >> ...
              >> In your case 'int A' in file 'A' is a definition of an identifier 'A'
              >> attached to an object of type 'int'. This identifier has external
              >> linkage by default, meaning that identifier 'A' is "exported", made
              >> accessible from other translation units. In order to access this[/color]
              > object[color=green]
              >> other translation units have to "import" this identifier by providing[/color]
              > an[color=green]
              >> 'extern' _declaration_ for it. That's exactly what you have in file[/color]
              > 'B'.
              >
              > That's the problem. Since global variable is regraded as "extern"
              > (is this right?), in other words, file A means:
              > <------------ file A ------------>
              > extern int A;
              > ...
              > A=10;
              > <------------ file B ------------>
              > extern int A;
              > if (A)
              > ...[/color]

              No. The original 'int A' was a _definition_ of an object with external
              linkage. 'extern int A' is a non-defining _declaration_ of an identifier
              with external linkage. These are not the same.

              'int A' defines an object with external linkage, but that doesn't mean
              that you can just add an explicit 'extern' keyword here and get the same
              thing. Adding 'extern' to 'int A' will have an unwanted side effect of
              turning this definition into a non-defining declaration.
              [color=blue]
              > Then how do I know which one is the defining occurrence of A?[/color]

              Neither. 'A' is not defined in the above files.
              [color=blue]
              > Does
              > the assignment on A=10 specify the declaraction "extern int A" in file
              > A is the definition?[/color]

              Assignment? How do intend to use assignment here?

              If you include an initializer into the declaration, this declaration
              will become a definition, even if you specify an explicit 'extern'

              extern int A; // non-defining declaration
              extern int A = 0; // definition

              --
              Best regards,
              Andrey Tarasevich

              Comment

              • Jason Curl

                #8
                Re: &quot;extern&qu ot; meaning

                ccwork wrote:[color=blue]
                > Andrey Tarasevich wrote:
                >[color=green]
                >>ccwork wrote:
                >>[color=darkred]
                >>> I am reading "C: A Reference Manual" 4th ed and I get lost for[/color][/color]
                >
                > the
                >[color=green][color=darkred]
                >>>"extern". It says that global object without specifying the
                >>>storage-class specifier will have "extern" as the default[/color][/color]
                >
                > storage-class
                >[color=green][color=darkred]
                >>>specifier. My (little) C experience tells me that an object with
                >>>"extern" is to let the linker knows that the object is referencing[/color][/color]
                >
                > the
                >[color=green][color=darkred]
                >>>object defined in somewhere, and this "somewhere" object does not[/color][/color]
                >
                > have
                >[color=green][color=darkred]
                >>>the storage-class specifier "extern". That is:
                >>> <------------ file A ------------>
                >>> int A;
                >>> ...
                >>> A=10;
                >>> <------------ file B ------------>
                >>> extern int A;
                >>> if (A)
                >>> ...
                >>>
                >>> But if the default storage-class specifier is "extern", then
                >>>variable "int A" is, indeed, "extern int A". Then who is the[/color][/color]
                >
                > definiting
                >[color=green][color=darkred]
                >>>occurence?
                >>> Please correct me if there is a mis-concept.[/color]
                >>
                >>C language doesn't not rely on the concept of "linker". There's no
                >>"linker" in C. At language level, external linkage of an identifier
                >>means just one thing - that this identifier refers to the same object
                >>(or function) in all translation units. How this requirement is
                >>implemented in practice (using that "linker" thingy or something[/color]
                >
                > else)
                >[color=green]
                >>is an implementation detail, a completely different story, irrelevant[/color]
                >
                > to
                >[color=green]
                >>the language itself.
                >>
                >>If you really want to think about this in terms of[/color]
                >
                > "exporting/importing"
                >[color=green]
                >>access to the object, think of it this way: when 'extern' is included[/color]
                >
                > in
                >[color=green]
                >>a _definition_ of some object, it "exports" the corresponding[/color]
                >
                > identifier
                >[color=green]
                >>to the outside world (i.e. other translation units), but when[/color]
                >
                > 'extern'
                >[color=green]
                >>is included in a mere _declaration_ of an object, it "imports" the
                >>identifier from the outside world.
                >>
                >>In your case 'int A' in file 'A' is a definition of an identifier 'A'
                >>attached to an object of type 'int'. This identifier has external
                >>linkage by default, meaning that identifier 'A' is "exported", made
                >>accessible from other translation units. In order to access this[/color]
                >
                > object
                >[color=green]
                >>other translation units have to "import" this identifier by providing[/color]
                >
                > an
                >[color=green]
                >>'extern' _declaration_ for it. That's exactly what you have in file[/color]
                >
                > 'B'.
                >
                > That's the problem. Since global variable is regraded as "extern"
                > (is this right?), in other words, file A means:
                > <------------ file A ------------>
                > extern int A;
                > ...
                > A=10;
                > <------------ file B ------------>
                > extern int A;
                > if (A)
                > ...
                >
                > Then how do I know which one is the defining occurrence of A? Does
                > the assignment on A=10 specify the declaraction "extern int A" in file
                > A is the definition? Or else?
                >[/color]

                'extern' indicates to the compiler the actual storage space is allocated
                elsewhere. Because now your example (is slightly different to above) has
                no 'int A', only 'extern int A', no storage space is actually created for A.

                Hence at link time there will be a failure as A is not defined anywhere.

                As for A=10, that doesn't actually allocate space, this is just an
                assignment, it has nothing to do with the definition of A.

                Comment

                • Lawrence Kirby

                  #9
                  Re: &quot;extern&qu ot; meaning

                  On Tue, 05 Apr 2005 18:06:28 -0700, ccwork wrote:
                  [color=blue]
                  > Hi all,
                  > I am reading "C: A Reference Manual" 4th ed and I get lost for the
                  > "extern". It says that global object without specifying the
                  > storage-class specifier will have "extern" as the default storage-class
                  > specifier.[/color]

                  C doesn't define the term "global". It is commonly used and misused in
                  different and contradictory ways. I assume the text above is referring to
                  declarations at file scope i.e. outside of any function.
                  [color=blue]
                  > My (little) C experience tells me that an object with
                  > "extern" is to let the linker knows that the object is referencing the
                  > object defined in somewhere, and this "somewhere" object does not have
                  > the storage-class specifier "extern". That is:
                  > <------------ file A ------------>
                  > int A;
                  > ...
                  > A=10;
                  > <------------ file B ------------>
                  > extern int A;
                  > if (A)
                  > ...
                  >
                  > But if the default storage-class specifier is "extern", then
                  > variable "int A" is, indeed, "extern int A". Then who is the definiting
                  > occurence?[/color]

                  It is incorrect to say that the default storage-class specifier is extern,
                  however it would be correct to say that the default linkage for file scope
                  declarations is external. The presence of extern in file B above makes a
                  difference, extern int A is just a declaration, it doesn't act as a
                  definition of A. int A; does (technically it is called a tentative
                  definition but the end resukt is that it is a definition here). Note that
                  providing an initialiser forces it to be a full definition, e.g.

                  extern int A = 1; /* Is a full definition */

                  Lawrence

                  Comment

                  • Mark McIntyre

                    #10
                    Re: &quot;extern&qu ot; meaning

                    On 5 Apr 2005 21:18:19 -0700, in comp.lang.c , "Peter Nilsson"
                    <airia@acay.com .au> wrote:
                    [color=blue]
                    >How does an implementation link _without_ a linker?[/color]

                    who knows - maybe it does runtime binding, like, er most OSen do...
                    [color=blue]
                    >Even C interpreters must have a linker, just as they must have
                    >a function call stack[/color]

                    Must they? Does it say that in the standard? .

                    --
                    Mark McIntyre
                    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
                    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >

                    Comment

                    • Christian Kandeler

                      #11
                      Re: &quot;extern&qu ot; meaning

                      Jason Curl wrote:
                      [color=blue]
                      > 'extern' indicates to the compiler the actual storage space is allocated
                      > elsewhere.[/color]

                      Not necessarily:
                      extern int a = 10;
                      This is a valid definition with external linkage.


                      Christian

                      Comment

                      • Mark McIntyre

                        #12
                        Re: &quot;extern&qu ot; meaning

                        On Wed, 06 Apr 2005 16:29:18 +0200, in comp.lang.c , Christian
                        Kandeler <christian.kand eler@hob.de_inv alid> wrote:
                        [color=blue]
                        >Jason Curl wrote:
                        >[color=green]
                        >> 'extern' indicates to the compiler the actual storage space is allocated
                        >> elsewhere.[/color]
                        >
                        >Not necessarily:
                        > extern int a = 10;
                        >This is a valid definition with external linkage.[/color]

                        Well yes, but this isn't relevant to Jason's point. All identifiers
                        at file scope have external linkage unless specified as static.

                        The extern tells the compiler to look elsewhere for a definition.
                        However if an initialisation is supplied, the storage class specifier
                        is ignored.

                        --
                        Mark McIntyre
                        CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
                        CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >

                        ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
                        http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                        ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                        Comment

                        • Andrey Tarasevich

                          #13
                          Re: &quot;extern&qu ot; meaning

                          Mark McIntyre wrote:[color=blue][color=green]
                          >> ...[color=darkred]
                          >>> 'extern' indicates to the compiler the actual storage space is allocated
                          >>> elsewhere.[/color]
                          >>
                          >>Not necessarily:
                          >> extern int a = 10;
                          >>This is a valid definition with external linkage.[/color]
                          >
                          > Well yes, but this isn't relevant to Jason's point. All identifiers
                          > at file scope have external linkage unless specified as static.
                          >
                          > The extern tells the compiler to look elsewhere for a definition.
                          > However if an initialisation is supplied, the storage class specifier
                          > is ignored.
                          > ...[/color]

                          While this description might be accurate enough for practical purposes,
                          it still does not match the approach to "external linkage" used in the
                          language specification.

                          'extern' specifier explicitly describes an identifier as having external
                          linkage. This is as true in cases when 'extern' is a part of a
                          non-defining declaration, as it is true in cases when 'extern' is a part
                          of a definition. When applied to a declaration, it indeed means that the
                          compiler has to look for a definition elsewhere. When applied to a
                          definition, its meaning is essentially reversed: it means that this
                          definition can be looked up from some other place.

                          --
                          Best regards,
                          Andrey Tarasevich

                          Comment

                          • Mark McIntyre

                            #14
                            Re: &quot;extern&qu ot; meaning

                            On Wed, 06 Apr 2005 13:38:54 -0700, in comp.lang.c , Andrey Tarasevich
                            <andreytarasevi ch@hotmail.com> wrote:
                            [color=blue]
                            >Mark McIntyre wrote:[color=green][color=darkred]
                            >>> ...
                            >>>> 'extern' indicates to the compiler the actual storage space is allocated
                            >>>> elsewhere.
                            >>>
                            >>>Not necessarily:
                            >>> extern int a = 10;
                            >>>This is a valid definition with external linkage.[/color]
                            >>
                            >> Well yes, but this isn't relevant to Jason's point. All identifiers
                            >> at file scope have external linkage unless specified as static.
                            >>
                            >> The extern tells the compiler to look elsewhere for a definition.
                            >> However if an initialisation is supplied, the storage class specifier
                            >> is ignored.
                            >> ...[/color]
                            >
                            >While this description might be accurate enough for practical purposes,
                            >it still does not match the approach to "external linkage" used in the
                            >language specification.[/color]

                            I actually think it does.
                            [color=blue]
                            >'extern' specifier explicitly describes an identifier as having external
                            >linkage.[/color]

                            Yes. But then at file scope, only objects with static storage-class
                            specifier have any other sort of linkage (6.2.2p5)
                            [color=blue]
                            >When applied to a
                            >definition, its meaning is essentially reversed: it means that this
                            >definition can be looked up from some other place.[/color]

                            This is true for /any/ non-static file-scope variable, by definition.
                            The storage-class specifier has no effect.

                            --
                            Mark McIntyre
                            CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
                            CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >

                            ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
                            http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                            ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                            Comment

                            • Chris Torek

                              #15
                              Re: &quot;extern&qu ot; meaning

                              >Mark McIntyre wrote:[color=blue][color=green]
                              >> Well yes, but this isn't relevant to Jason's point. All identifiers
                              >> at file scope have external linkage unless specified as static.[/color][/color]

                              (There is an exception to this rule; see below.)
                              [color=blue][color=green]
                              >> The extern tells the compiler to look elsewhere for a definition.
                              >> However if an initialisation is supplied, the storage class specifier
                              >> is ignored.[/color][/color]

                              In article <1158i5hkfirob9 d@news.supernew s.com>
                              Andrey Tarasevich <andreytarasevi ch@hotmail.com> wrote:[color=blue]
                              >While this description might be accurate enough for practical purposes,
                              >it still does not match the approach to "external linkage" used in the
                              >language specification.[/color]

                              Yes. But the real problem here is confusion between the keyword
                              "extern", which is syntactically a storage-class specifier (in the
                              same group as "static", "register", and "typedef"), and "external
                              linkage", which has almost nothing to do with the keyword. In C's
                              tradition of misusing the English language, :-) the word "extern"
                              is not required to mean "external linkage", so it does not. The
                              "const" keyword does not define constants, "typedef" does not define
                              new types, and "extern" does not mean external linkage. (Similarly,
                              "static" sometimes means "static storage" and sometimes means
                              something else entirely, as will appear below.)
                              [color=blue]
                              >'extern' specifier explicitly describes an identifier as having external
                              >linkage. This is as true in cases when 'extern' is a part of a
                              >non-defining declaration, as it is true in cases when 'extern' is a part
                              >of a definition. When applied to a declaration, it indeed means that the
                              >compiler has to look for a definition elsewhere. When applied to a
                              >definition, its meaning is essentially reversed: it means that this
                              >definition can be looked up from some other place.[/color]

                              I am not sure what you mean to say with that last sentence. I think
                              the only way to fully describe the "extern" keyword is to exhaustively
                              enumerate all the ways in which it can be used with a variable-name.
                              These are:

                              /* all outside a function */
                              int a; /* not extern */
                              extern int b;

                              int d = 0;
                              extern int e = 0;

                              static int g;
                              extern int g;
                              int g;
                              int g = 42;

                              void func(void) {
                              extern int h;
                              int i;
                              static int j;
                              }

                              Here "a" is both declared and defined, because we omitted the
                              extern keyword. We have no initializer so this is a "tentative
                              definition" -- we can later write "int a = 3" to set a to 3
                              instead of the default 0, but by the end of the translation
                              unit, the variable will be defined.

                              The variable "b", on the other hand, is only declared. The
                              extern keyword suppresses the tentative definition. This is
                              its only real function when applied to file-scope variables:
                              it only ever suppresses definitions, and only when they would
                              have been tentative anyway (as we will see with "e").

                              Next we have d and e, which are declared-and-defined and both
                              explicitly initialized. These are not tentative definitions
                              so the "extern" keyword has no effect -- it can only suppress
                              tentative definitions.

                              Now we have g. This is one of the more peculiar cases. By first
                              declaring it "static", and not using an initializer, we create a
                              tentative definition and inhibit the default linkage (external
                              linkage) -- we wind up with a file-scope g with internal linkage,
                              which will be initialized to 0 if we do not override this. The
                              second declaration uses the "extern" keyword. In this case, the
                              keyword *also* means "static", because we already have a definition
                              of the same identifier at the same scope. When the identifier is
                              already defined, "extern" means "whatever linkage it had before".
                              The third declaration for "g" *also* means "static": the absence
                              of the "extern" keyword fails to suppress tentative-definition-ness,
                              but has no effect on linkage, because the default linkage behavior
                              is to act as if the "extern" keyword had been present. Finally,
                              the fourth line for "g" is a real, solid, actual definition -- not
                              tentative -- and gives it the value 4. As before, the nonexistent
                              extern keyword has no effect on linkage: the linkage is the same
                              as if we had used the extern keyword, and is still "static". All
                              four declarations mean the same thing, but only the fourth is
                              a non-tentative definition.

                              The "extern" keyword does sometimes means something more than
                              "suppress tentative definition", though, and this appears inside
                              the function func(). The variable h is declared (but not
                              defined) as having external linkage. Its scope is limited;
                              the declaration disappears after the "}" that ends the function.
                              The variable i is both declared and defined, and has automatic
                              storage duration; and the variable j is also both declared and
                              defined, and has static storage duration.

                              Note that all file-scope variables always have static duration:
                              a, b, d, e, and g are all static-duration variables. Like the
                              "extern" keyword, the "static" keyword would be redundant; so, like
                              the "extern" keyword, the "static" keyword is given a new and
                              unrelated meaning: it alters the identifier's linkage. The
                              "non-static" variables (a, b, d, and e) have external linkage, but
                              the "static" variable (g) has internal linkage.

                              We can now summarize this:

                              extern:
                              If a variable would have had no linkage (and thus automatic
                              storage duration), this keyword gives it linkage, usually
                              external, but sometimes internal. If the variable would
                              already have had external or internal linkage, the "extern"
                              keyword has no effect on linkage; instead, it suppresses
                              tentative definitions, but not actual definitions.

                              static:
                              If a variable would have had automatic storage duration
                              (and thus no linkage), this keyword gives it static storage
                              duration instead. Otherwise, it gives the variable internal
                              linkage.

                              These two keywords can also be applied to function-names, but since
                              functions never have storage duration to worry about, the situation
                              there is simpler: "extern" has no effect, and "static" only affects
                              linkage.

                              There is one situation I deliberately glossed over. It is possible
                              to give the same identifier both internal and external linkage in
                              the same translation unit. We do this by hiding the internal-linkage
                              name with a function-scope name, then using the "extern" keyword:

                              static int x; /* internal linkage, file scope, static duration */

                              void f(void) {
                              int x; /* hides the internal-linkage x */
                              {
                              extern int x; /* BAD - DO NOT DO THIS */
                              }
                              }

                              The C Standards (C89 and C99 both) say that the behavior here is
                              undefined. We simply do not know what will happen -- will we
                              get this translation unit's x, or some other translation unit's
                              x, or will things just go kaboom? It is probably wisest not to
                              find out the hard way. :-)
                              --
                              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.

                              Comment

                              Working...