extern

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

    #1

    extern

    Can anyone explain me what extern is used for? I thought it was used to
    declare variables definited in other files, but i can do that also
    without extern.

    /*file a.c*/
    int a=5;
    int main()
    {
    f();
    }

    /*file b.c*/
    int a;
    void f()
    {
    printf("%d\n",a ); /*it prints 5*/
    }


    Another thing, what happens if i declare a function like this: extern
    int fn(void) ?

    --
    Devaraja (Xdevaraja87^gm ail^c0mX)
    Linux Registerd User #338167

  • ade ishs

    #2
    Re: extern

    DevarajA wrote:[color=blue]
    > Can anyone explain me what extern is used for? I thought it was used to
    > declare variables definited in other files, but i can do that also
    > without extern.
    >
    > /*file a.c*/
    > int a=5;
    > int main()
    > {
    > f();
    > }
    >
    > /*file b.c*/
    > int a;
    > void f()
    > {
    > printf("%d\n",a ); /*it prints 5*/
    > }
    >
    >
    > Another thing, what happens if i declare a function like this: extern
    > int fn(void) ?[/color]

    <quote>
    If the declaration of an identifier for a function has no
    storage-class specifier, its linkage is determined exactly as if it
    were declared with the storage-class specifier extern . If the
    declaration of an identifier for an object has file scope and no
    storage-class specifier, its linkage is external.
    </quote>

    --
    ade ishs

    Comment

    • Jack Klein

      #3
      Re: extern

      On Tue, 19 Jul 2005 13:13:33 GMT, DevarajA <no@spam.com> wrote in
      comp.lang.c:
      [color=blue]
      > Can anyone explain me what extern is used for? I thought it was used to
      > declare variables definited in other files, but i can do that also
      > without extern.
      >
      > /*file a.c*/
      > int a=5;
      > int main()
      > {
      > f();
      > }
      >
      > /*file b.c*/
      > int a;
      > void f()
      > {
      > printf("%d\n",a ); /*it prints 5*/
      > }[/color]

      File b.c has undefined behavior, calling the variadic function
      printf() without a prototype in scope, but let's skip that for the
      moment.

      If you compile these two source files and combine them into a single
      executable, you produce undefined behavior. One consequence of
      undefined behavior is seeming to work like you expect it to. On other
      compiler/linker combinations, you might well get an error from the
      linker and no executable produced.

      For every function or object with external linkage in a C program
      there must be:

      1. Either zero or one external definitions of the function or object,
      if it is not actually referenced in the program.

      2. Exactly one external definition of the function or object, if it
      is actually referenced in the program.
      [color=blue]
      > Another thing, what happens if i declare a function like this: extern
      > int fn(void) ?[/color]

      The extern keyword is redundant on function definitions, declarations,
      and prototypes. They have external linkage by default, which is
      changed to internal linkage by the use of the static keyword.

      --
      Jack Klein
      Home: http://JK-Technology.Com
      FAQs for
      comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
      comp.lang.c++ http://www.parashift.com/c++-faq-lite/
      alt.comp.lang.l earn.c-c++

      Comment

      • Me

        #4
        Re: extern

        DevarajA wrote:[color=blue]
        > Can anyone explain me what extern is used for? I thought it was used to
        > declare variables definited in other files, but i can do that also
        > without extern.[/color]

        I'd *highly* suggest you use the extern keyword when declaring external
        variables as opposed to just using:

        int a;

        because this looks like you're defining a global variable that gets
        zero initialized as opposed to declaring a global variable defined in
        another translation unit
        [color=blue]
        > /*file a.c*/
        > int a=5;
        > int main()
        > {
        > f();
        > }
        >
        > /*file b.c*/
        > int a;
        > void f()
        > {
        > printf("%d\n",a ); /*it prints 5*/
        > }[/color]

        You can also do this:

        void f()
        {
        extern int a;
        printf("%d\n",a ); /*it prints 5*/
        }

        Without introducing a symbol to the entire file of b.c
        [color=blue]
        > Another thing, what happens if i declare a function like this: extern
        > int fn(void) ?[/color]

        Same thing that happens when you declare it without the extern.

        Comment

        • Me

          #5
          Re: extern

          Me wrote:[color=blue]
          > DevarajA wrote:[color=green]
          > > Can anyone explain me what extern is used for? I thought it was used to
          > > declare variables definited in other files, but i can do that also
          > > without extern.[/color]
          >
          > I'd *highly* suggest you use the extern keyword when declaring external
          > variables as opposed to just using:
          >
          > int a;
          >
          > because this looks like you're defining a global variable that gets
          > zero initialized as opposed to declaring a global variable defined in
          > another translation unit
          >[color=green]
          > > /*file a.c*/
          > > int a=5;
          > > int main()
          > > {
          > > f();
          > > }
          > >
          > > /*file b.c*/
          > > int a;
          > > void f()
          > > {
          > > printf("%d\n",a ); /*it prints 5*/
          > > }[/color][/color]

          Ok, I'm talking crap here based on information I vaguely remember from
          something I read a long time ago (it probably had something to do with
          an ancient unix compiler). What you're doing in b.c is called a
          tentative definition:

          6.9.2/2 "A declaration of an identifier for an object that has file
          scope without an initializer, and without a storage-class specifier or
          with the storage-class specifier static, constitutes a tentative
          definition. If a translation unit contains one or more tentative
          definitions for an identifier, and the translation unit contains no
          external definition for that identifier, then the behavior is exactly
          as if the translation unit contains a file scope declaration of that
          identifier, with the composite type as of the end of the translation
          unit, with an initializer equal to 0."

          So as you can see, Jack Klein's answer was right about undefined
          behavior occuring if you link these two files together because in b.c,
          the compiler acts as if you have:

          int a = 0;

          at the very bottom.

          Comment

          • DevarajA

            #6
            Re: extern

            Me ha scritto:[color=blue]
            > Me wrote:
            >[color=green]
            >>DevarajA wrote:
            >>[color=darkred]
            >>>Can anyone explain me what extern is used for? I thought it was used to
            >>>declare variables definited in other files, but i can do that also
            >>>without extern.[/color]
            >>
            >>I'd *highly* suggest you use the extern keyword when declaring external
            >>variables as opposed to just using:
            >>
            >>int a;
            >>
            >>because this looks like you're defining a global variable that gets
            >>zero initialized as opposed to declaring a global variable defined in
            >>another translation unit
            >>
            >>[color=darkred]
            >>>/*file a.c*/
            >>>int a=5;
            >>>int main()
            >>>{
            >>>f();
            >>>}
            >>>
            >>>/*file b.c*/
            >>>int a;
            >>>void f()
            >>>{
            >>>printf("%d\n ",a); /*it prints 5*/
            >>>}[/color][/color]
            >
            >
            > Ok, I'm talking crap here based on information I vaguely remember from
            > something I read a long time ago (it probably had something to do with
            > an ancient unix compiler). What you're doing in b.c is called a
            > tentative definition:
            >
            > 6.9.2/2 "A declaration of an identifier for an object that has file
            > scope without an initializer, and without a storage-class specifier or
            > with the storage-class specifier static, constitutes a tentative
            > definition. If a translation unit contains one or more tentative
            > definitions for an identifier, and the translation unit contains no
            > external definition for that identifier, then the behavior is exactly
            > as if the translation unit contains a file scope declaration of that
            > identifier, with the composite type as of the end of the translation
            > unit, with an initializer equal to 0."
            >
            > So as you can see, Jack Klein's answer was right about undefined
            > behavior occuring if you link these two files together because in b.c,
            > the compiler acts as if you have:
            >[/color]

            So if in file b.c i had declared extern int a it would just have
            looked for an int a in another translation unit?

            --
            Devaraja (Xdevaraja87^gm ail^c0mX)
            Linux Registerd User #338167

            Comment

            • Mark McIntyre

              #7
              Re: extern

              On Tue, 19 Jul 2005 13:13:33 GMT, in comp.lang.c , DevarajA
              <no@spam.com> wrote:
              [color=blue]
              >Can anyone explain me what extern is used for?[/color]

              For non-function type things, declaring objects whose definition is
              elsewhere.
              [color=blue]
              >I thought it was used to
              >declare variables definited in other files, but i can do that also
              >without extern[/color]

              Sure - at file scope, an object with no storage class is by default
              extern. IMHO however its bad practice not to use extern, as its a
              good signal to the maintenance crew that they need to look elsewhere
              for the actual definition of 'a';


              --
              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

              • Flash Gordon

                #8
                Re: extern

                Mark McIntyre wrote:[color=blue]
                > On Tue, 19 Jul 2005 13:13:33 GMT, in comp.lang.c , DevarajA
                > <no@spam.com> wrote:
                >[color=green]
                >>Can anyone explain me what extern is used for?[/color]
                >
                > For non-function type things, declaring objects whose definition is
                > elsewhere.[/color]

                Yes.
                [color=blue][color=green]
                >>I thought it was used to
                >>declare variables definited in other files, but i can do that also
                >>without extern[/color]
                >
                > Sure - at file scope, an object with no storage class is by default
                > extern.[/color]

                Wrong.

                A function declaration without "static" is extern by default, but that
                is not true for objects. For objects it is a "tentative declaration" NOT
                an extern, although it has external linkage (i.e. other translation
                units can access it). If nothing else is seen by the end of the
                translation unit then it is as if there was a declaration with a 0
                initialiser at the end of the translation unit.

                To quote from n1124:
                " 6.9.2 External object definitions Semantics
                1 If the declaration of an identifier for an object has file scope
                and an initializer, the declaration is an external definition for
                the identifier.
                2 A declaration of an identifier for an object that has file scope
                without an initializer, and without a storage-class specifier or
                with the storage-class specifier static, constitutes a tentative
                definition. If a translation unit contains one or more tentative
                definitions for an identifier, and the translation unit contains
                no external definition for that identifier, then the behavior is
                exactly as if the translation unit contains a file scope
                declaration of that identifier, with the composite type as of the
                end of the translation unit, with an initializer equal to 0.
                [color=blue]
                > IMHO however its bad practice not to use extern, as its a
                > good signal to the maintenance crew that they need to look elsewhere
                > for the actual definition of 'a';[/color]

                It is worse than bad practice because otherwise you invoke undefined
                behaviour.
                --
                Flash Gordon
                Living in interesting times.
                Although my email address says spam, it is real and I read it.

                Comment

                • Mark McIntyre

                  #9
                  Re: extern

                  On Tue, 19 Jul 2005 21:43:12 -0500, in comp.lang.c , Jack Klein
                  <jackklein@spam cop.net> wrote:
                  [color=blue][color=green]
                  >> /*file a.c*/
                  >> int a=5;
                  >>
                  >> /*file b.c*/
                  >> int a;[/color]
                  >If you compile these two source files and combine them into a single
                  >executable, you produce undefined behavior.[/color]

                  You sure? The second behaves exactly as if it had been declared
                  extern int a;
                  [color=blue]
                  >For every function or object with external linkage in a C program
                  >there must be:
                  >
                  >1. Either zero or one external definitions of the function or object,
                  >if it is not actually referenced in the program.
                  >
                  >2. Exactly one external definition of the function or object, if it
                  >is actually referenced in the program.[/color]

                  This is true. However the 2nd is a declaration, not a definition.


                  --
                  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

                  • Lawrence Kirby

                    #10
                    Re: extern

                    On Wed, 20 Jul 2005 12:03:08 +0100, Mark McIntyre wrote:
                    [color=blue]
                    > On Tue, 19 Jul 2005 21:43:12 -0500, in comp.lang.c , Jack Klein
                    > <jackklein@spam cop.net> wrote:
                    >[color=green][color=darkred]
                    >>> /*file a.c*/
                    >>> int a=5;
                    >>>
                    >>> /*file b.c*/
                    >>> int a;[/color]
                    >>If you compile these two source files and combine them into a single
                    >>executable, you produce undefined behavior.[/color]
                    >
                    > You sure? The second behaves exactly as if it had been declared
                    > extern int a;[/color]

                    Both have identical (external) linkage but their behaviour in terms of
                    whether they create a definition is different.
                    [color=blue][color=green]
                    >>For every function or object with external linkage in a C program
                    >>there must be:
                    >>
                    >>1. Either zero or one external definitions of the function or object,
                    >>if it is not actually referenced in the program.
                    >>
                    >>2. Exactly one external definition of the function or object, if it
                    >>is actually referenced in the program.[/color]
                    >
                    > This is true. However the 2nd is a declaration, not a definition.[/color]

                    extern int a;

                    is just a declaration.

                    int a;

                    is a tentative definition (assuming file scope). Its presence ensures that
                    there will be a definition of a by the end of the translation unit of b.c.
                    As such both a.c and b.c contain a definition of a so linking them
                    produces undefined behaviour.

                    It is called a tentative definition because it allows other tentative
                    definitions and a full definition in the same translation unit, e.g.

                    int a;
                    int a;
                    int a = 1;

                    is valid.

                    Lawrence

                    Comment

                    • DevarajA

                      #11
                      Re: extern

                      Lawrence Kirby ha scritto:[color=blue]
                      > On Wed, 20 Jul 2005 12:03:08 +0100, Mark McIntyre wrote:
                      >
                      >[color=green]
                      >>On Tue, 19 Jul 2005 21:43:12 -0500, in comp.lang.c , Jack Klein
                      >><jackklein@sp amcop.net> wrote:
                      >>
                      >>[color=darkred]
                      >>>>/*file a.c*/
                      >>>>int a=5;
                      >>>>
                      >>>>/*file b.c*/
                      >>>>int a;
                      >>>
                      >>>If you compile these two source files and combine them into a single
                      >>>executable , you produce undefined behavior.[/color]
                      >>
                      >>You sure? The second behaves exactly as if it had been declared
                      >>extern int a;[/color]
                      >
                      >
                      > Both have identical (external) linkage but their behaviour in terms of
                      > whether they create a definition is different.
                      >
                      >[color=green][color=darkred]
                      >>>For every function or object with external linkage in a C program
                      >>>there must be:
                      >>>
                      >>>1. Either zero or one external definitions of the function or object,
                      >>>if it is not actually referenced in the program.
                      >>>
                      >>>2. Exactly one external definition of the function or object, if it
                      >>>is actually referenced in the program.[/color]
                      >>
                      >>This is true. However the 2nd is a declaration, not a definition.[/color]
                      >
                      >
                      > extern int a;
                      >
                      > is just a declaration.
                      >
                      > int a;
                      >
                      > is a tentative definition (assuming file scope). Its presence ensures that
                      > there will be a definition of a by the end of the translation unit of b.c.
                      > As such both a.c and b.c contain a definition of a so linking them
                      > produces undefined behaviour.
                      >[/color]

                      /*file a.c*/
                      int var2;
                      int main()
                      {
                      var2=99;
                      return 0;
                      }

                      I compiled into an object file (on linux) with:
                      $ gcc a.c -c -o a.obj
                      and then i printed it's symbol table with:
                      $ nm a.obj
                      This is the output:

                      00000000 T main
                      00000004 C var2

                      where "C" means "The symbol is common. Common symbols are uninitialized
                      data. When linking, multiple common symbols may appear with the same
                      name. If the symbol is defined anywhere, the common symbols are treated
                      as undefined references." (from nm man page)

                      --
                      Devaraja (Xdevaraja87^gm ail^c0mX)
                      Linux Registerd User #338167

                      Comment

                      • Christian Kandeler

                        #12
                        Re: extern

                        DevarajA wrote:
                        [color=blue]
                        > /*file a.c*/
                        > int var2;
                        > int main()
                        > {
                        > var2=99;
                        > return 0;
                        > }[/color]

                        The second var2 does not have the same scope as the first one, which makes
                        this example totally irrelevant to the topic of this thread.


                        Christian

                        Comment

                        • DevarajA

                          #13
                          Re: extern

                          Christian Kandeler ha scritto:[color=blue]
                          > DevarajA wrote:
                          >
                          >[color=green]
                          >>/*file a.c*/
                          >>int var2;
                          >>int main()
                          >>{
                          >> var2=99;
                          >> return 0;
                          >>}[/color]
                          >
                          >
                          > The second var2 does not have the same scope as the first one, which makes
                          > this example totally irrelevant to the topic of this thread.[/color]

                          There's not a second var2. I've just assigned to it


                          --
                          Devaraja (Xdevaraja87^gm ail^c0mX)
                          Linux Registerd User #338167

                          Comment

                          • Chris Torek

                            #14
                            Re: extern

                            In article <sysDe.184979$7 5.8009312@news4 .tin.it>
                            DevarajA <no@spam.com> wrote:[color=blue]
                            >I compiled into an object file (on linux) with:
                            >$ gcc a.c -c -o a.obj
                            >and then i printed it's symbol table with:
                            >$ nm a.obj
                            >This is the output:
                            >
                            >00000000 T main
                            >00000004 C var2
                            >
                            >where "C" means "The symbol is common. ...[/color]

                            The so-called "common model", in which var2 uses this "common
                            symbol" trick, is *optional*: C compilers are not required to
                            implement one. They may instead use a "def/ref model".

                            If your C compiler used a def/ref model, the "nm" output for the
                            above would give var2 the "D" type. Changing the declaration
                            for var2 to "extern int var2" would give it the "U" type.

                            C compilers on Unix-like systems never use the def/ref model,
                            because there are gigabytes of Unix-like-system "freeware" source
                            code that *require* common-model. C compilers on some other systems
                            *do* use def/ref, and that code fails to compile on them. (C++
                            compilers also do use def/ref, even on Unix-like systems.)
                            --
                            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

                            • Old Wolf

                              #15
                              Re: extern

                              Flash Gordon wrote:[color=blue]
                              > Mark McIntyre wrote:[color=green]
                              >>
                              >> Sure - at file scope, an object with no storage class is by default
                              >> extern.[/color]
                              >
                              > Wrong.
                              >
                              > A function declaration without "static" is extern by default, but that
                              > is not true for objects. For objects it is a "tentative declaration" NOT
                              > an extern, although it has external linkage (i.e. other translation
                              > units can access it). If nothing else is seen by the end of the
                              > translation unit then it is as if there was a declaration with a 0
                              > initialiser at the end of the translation unit.[/color]

                              Firstly, it is /tentative definition/, not declaration.

                              Also, Mark McIntyre was taking about objects.
                              The tentative definition in question has external linkage.
                              The object it identifies must also have external linkage --
                              whether it is later explicitly declared or not.

                              Mark McIntyre's comment seems correct; I don't understand the
                              distinction you draw between an object being "an extern",
                              vs. "having external linkage".

                              Comment

                              Working...