External object definition and linkage

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

    External object definition and linkage

    After many years of dealing with definition and linkage issues
    in ways that I know to be safe, I've decided it's time to try
    to understand this area properly. Consider a header file with
    the file scope declaration

    int i;

    This header is included in two files that refer to i but do not
    declare it. The two files build together into a single program.

    i is therefore declared once in each translation unit. According
    to C99 6.2.2 the declarations have external linkage and refer to
    the same object. 6.9.2 says that each declaration is a tentative
    external definition, which then gets converted to an actual
    external definition. There are now 2 external definitions of i
    in the program, which breaks the requirement in 6.9 that there
    shall be exactly one external definition, so this results in
    undefined behavior.

    Have I got this right? Confirmation or correction appreciated.
  • Leor Zolman

    #2
    Re: External object definition and linkage

    On 2 Apr 2004 13:05:42 -0800, jjf@bcs.org.uk (J. J. Farrell) wrote:
    [color=blue]
    >After many years of dealing with definition and linkage issues
    >in ways that I know to be safe, I've decided it's time to try
    >to understand this area properly. Consider a header file with
    >the file scope declaration
    >
    > int i;
    >
    >This header is included in two files that refer to i but do not
    >declare it. The two files build together into a single program.
    >
    >i is therefore declared once in each translation unit. According
    >to C99 6.2.2 the declarations have external linkage and refer to
    >the same object. 6.9.2 says that each declaration is a tentative
    >external definition, which then gets converted to an actual
    >external definition. There are now 2 external definitions of i
    >in the program, which breaks the requirement in 6.9 that there
    >shall be exactly one external definition, so this results in
    >undefined behavior.
    >
    >Have I got this right? Confirmation or correction appreciated.[/color]

    The language of 6.9.2/2 is, IMHO, horribly ambiguous. Here's it is (I've
    used quotes to indicate what is in italics in the Standard):

    -----------------
    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 what's that word "declaratio n" doing there on the next-to-last line? How
    can a "declaratio n" have an "initialize r equal to 0" (or behave "as if" it
    had one) without being considered "the definition" of the object across all
    TU's? I don't know.

    Note that this is not within a constraints section, and therefore whatever
    it means, the compiler is not obliged to produce a diagnostic if it is
    violated. So it could in fact be saying that there's only supposed to be
    one, but if an implementation carries the "tentativen ess" over to the link
    phase, and it works as someone would expect it to (or be used to it working
    from a historical basis), that isn't necessarily a non-conforming
    implementation.

    [Admission: I had some help from Greg Comeau on this, and he essentially
    confirmed my own confusion about it all. But I hadn't thought about the
    implications of it not being in a constraints section...]
    -leor




    --
    Leor Zolman --- BD Software --- www.bdsoft.com
    On-Site Training in C/C++, Java, Perl and Unix
    C++ users: Download BD Software's free STL Error Message Decryptor at:
    An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

    Comment

    • Eric Sosman

      #3
      Re: External object definition and linkage

      "J. J. Farrell" wrote:[color=blue]
      >
      > After many years of dealing with definition and linkage issues
      > in ways that I know to be safe, I've decided it's time to try
      > to understand this area properly. Consider a header file with
      > the file scope declaration
      >
      > int i;
      >
      > This header is included in two files that refer to i but do not
      > declare it. The two files build together into a single program.
      >
      > i is therefore declared once in each translation unit. According
      > to C99 6.2.2 the declarations have external linkage and refer to
      > the same object. 6.9.2 says that each declaration is a tentative
      > external definition, which then gets converted to an actual
      > external definition. There are now 2 external definitions of i
      > in the program, which breaks the requirement in 6.9 that there
      > shall be exactly one external definition, so this results in
      > undefined behavior.
      >
      > Have I got this right? Confirmation or correction appreciated.[/color]

      You're right.

      The usual practice (for any externally-linked object or
      function) is to put a declaration, not a definition, in a
      header file, and to #include that header wherever it's needed.
      The actual definition goes in one and only one .c file, which
      itself also #include's the header (so the compiler can complain
      if the declaration and the definition disagree).

      In your case, the header would say

      extern int i;

      .... where "extern" means, roughly, "this is just a declaration;
      there's a matching definition somewhere else." For a function
      you could say

      extern int func(void);

      .... except it turns out that "extern" is unnecessary (although
      harmless) here: The compiler can tell it's not a definition
      because there's no `{...}' function body.

      One final point: Many people feel that "global variables"
      are Bad, mostly because they can create hard-to-see couplings
      between apparently unrelated parts of the program. I'm less
      bitterly opposed to them than some denizens hereabouts, but
      whenever I stick a global variable into my program I pause
      and consider whether this is *really* the right thing to do.
      Quite often, it isn't.

      --
      Eric.Sosman@sun .com

      Comment

      • Leor Zolman

        #4
        Re: External object definition and linkage

        On Fri, 02 Apr 2004 18:31:34 -0500, Eric Sosman <Eric.Sosman@su n.com>
        wrote:
        [color=blue]
        >
        > The usual practice (for any externally-linked object or
        >function) is to put a declaration, not a definition, in a
        >header file, and to #include that header wherever it's needed.
        >The actual definition goes in one and only one .c file, which
        >itself also #include's the header (so the compiler can complain
        >if the declaration and the definition disagree).
        >
        > In your case, the header would say
        >
        > extern int i;
        >
        >... where "extern" means, roughly, "this is just a declaration;
        >there's a matching definition somewhere else."[/color]

        Being my usual literal-minded-self, I answered the OP's specific question
        the best I could...but now I feel obliged to add that the way Eric says to
        do things is of course the /right/ way to set up inter-TU linkage, since it
        is completely unambiguous and works the same in both C and C++.

        Trying to understand the situation where "int i;" appears at file scope in
        multiple TU's is seems better to be left an exercise in Standard
        decryption, and probably shouldn't be allowed to become a practical matter
        ;-)
        -leor

        --
        Leor Zolman --- BD Software --- www.bdsoft.com
        On-Site Training in C/C++, Java, Perl and Unix
        C++ users: Download BD Software's free STL Error Message Decryptor at:
        An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

        Comment

        • CBFalconer

          #5
          Re: External object definition and linkage

          "J. J. Farrell" wrote:[color=blue]
          >
          > After many years of dealing with definition and linkage issues
          > in ways that I know to be safe, I've decided it's time to try
          > to understand this area properly. Consider a header file with
          > the file scope declaration
          >
          > int i;
          >
          > This header is included in two files that refer to i but do not
          > declare it. The two files build together into a single program.[/color]

          and is thus a mistake. You omitted the word "extern".
          [color=blue]
          >
          > i is therefore declared once in each translation unit. According
          > to C99 6.2.2 the declarations have external linkage and refer to
          > the same object. 6.9.2 says that each declaration is a tentative
          > external definition, which then gets converted to an actual
          > external definition. There are now 2 external definitions of i
          > in the program, which breaks the requirement in 6.9 that there
          > shall be exactly one external definition, so this results in
          > undefined behavior.
          >
          > Have I got this right? Confirmation or correction appreciated.[/color]

          No. Header files should only specify the exposure of elements in
          the source. They should not declare any data or functions.

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

          • CBFalconer

            #6
            Re: External object definition and linkage

            CBFalconer wrote:[color=blue]
            >
            > "J. J. Farrell" wrote:[color=green]
            > >
            > > After many years of dealing with definition and linkage issues
            > > in ways that I know to be safe, I've decided it's time to try
            > > to understand this area properly. Consider a header file with
            > > the file scope declaration
            > >
            > > int i;
            > >
            > > This header is included in two files that refer to i but do not
            > > declare it. The two files build together into a single program.[/color]
            >
            > and is thus a mistake. You omitted the word "extern".
            >[color=green]
            > >
            > > i is therefore declared once in each translation unit. According
            > > to C99 6.2.2 the declarations have external linkage and refer to
            > > the same object. 6.9.2 says that each declaration is a tentative
            > > external definition, which then gets converted to an actual
            > > external definition. There are now 2 external definitions of i
            > > in the program, which breaks the requirement in 6.9 that there
            > > shall be exactly one external definition, so this results in
            > > undefined behavior.
            > >
            > > Have I got this right? Confirmation or correction appreciated.[/color]
            >
            > No. Header files should only specify the exposure of elements in
            > the source. They should not declare any data or functions.[/color]

            Quick, change that 'declare' to 'define', before the rats get at
            it.

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

            • J. J. Farrell

              #7
              Re: External object definition and linkage


              "Leor Zolman" <leor@bdsoft.co m> wrote in message
              news:m7sr60larf 12h3s7pvhnh42kl pjvrf6o6h@4ax.c om...[color=blue]
              > On 2 Apr 2004 13:05:42 -0800, jjf@bcs.org.uk (J. J. Farrell) wrote:
              >[color=green]
              > >After many years of dealing with definition and linkage issues
              > >in ways that I know to be safe, I've decided it's time to try
              > >to understand this area properly. Consider a header file with
              > >the file scope declaration
              > >
              > > int i;
              > >
              > >This header is included in two files that refer to i but do not
              > >declare it. The two files build together into a single program.
              > >
              > >i is therefore declared once in each translation unit. According
              > >to C99 6.2.2 the declarations have external linkage and refer to
              > >the same object. 6.9.2 says that each declaration is a tentative
              > >external definition, which then gets converted to an actual
              > >external definition. There are now 2 external definitions of i
              > >in the program, which breaks the requirement in 6.9 that there
              > >shall be exactly one external definition, so this results in
              > >undefined behavior.
              > >
              > >Have I got this right? Confirmation or correction appreciated.[/color]
              >
              > The language of 6.9.2/2 is, IMHO, horribly ambiguous. Here's it is (I've
              > used quotes to indicate what is in italics in the Standard):
              >
              > -----------------
              > A declaration of an identifier for an object that has file scope without[/color]
              an[color=blue]
              > 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[/color]
              0.[color=blue]
              > ----------------
              >
              > So what's that word "declaratio n" doing there on the next-to-last line?[/color]
              How[color=blue]
              > can a "declaratio n" have an "initialize r equal to 0" (or behave "as if" it
              > had one) without being considered "the definition" of the object across[/color]
              all[color=blue]
              > TU's? I don't know.[/color]

              I don't think it can - that's the point. I guess they avoided "definition "
              since this is the section that's defining "definition ".
              [color=blue]
              > Note that this is not within a constraints section, and therefore whatever
              > it means, the compiler is not obliged to produce a diagnostic if it is
              > violated. So it could in fact be saying that there's only supposed to be
              > one, but if an implementation carries the "tentativen ess" over to the link
              > phase, and it works as someone would expect it to (or be used to it[/color]
              working[color=blue]
              > from a historical basis), that isn't necessarily a non-conforming
              > implementation.[/color]

              I think it just means that it results in undefined behaviour. The
              pre-standard compilers that implemented the 'common model' can continue
              to do so, and other compilers don't have to do anything in particular.



              Comment

              • J. J. Farrell

                #8
                Re: External object definition and linkage


                "Leor Zolman" <leor@bdsoft.co m> wrote in message
                news:m7sr60larf 12h3s7pvhnh42kl pjvrf6o6h@4ax.c om...[color=blue]
                > On 2 Apr 2004 13:05:42 -0800, jjf@bcs.org.uk (J. J. Farrell) wrote:
                >[color=green]
                > >After many years of dealing with definition and linkage issues
                > >in ways that I know to be safe, I've decided it's time to try
                > >to understand this area properly. Consider a header file with
                > >the file scope declaration
                > >
                > > int i;
                > >
                > >This header is included in two files that refer to i but do not
                > >declare it. The two files build together into a single program.
                > >
                > >i is therefore declared once in each translation unit. According
                > >to C99 6.2.2 the declarations have external linkage and refer to
                > >the same object. 6.9.2 says that each declaration is a tentative
                > >external definition, which then gets converted to an actual
                > >external definition. There are now 2 external definitions of i
                > >in the program, which breaks the requirement in 6.9 that there
                > >shall be exactly one external definition, so this results in
                > >undefined behavior.
                > >
                > >Have I got this right? Confirmation or correction appreciated.[/color]
                >
                > The language of 6.9.2/2 is, IMHO, horribly ambiguous. Here's it is (I've
                > used quotes to indicate what is in italics in the Standard):
                >
                > -----------------
                > A declaration of an identifier for an object that has file scope without[/color]
                an[color=blue]
                > 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[/color]
                0.[color=blue]
                > ----------------
                >
                > So what's that word "declaratio n" doing there on the next-to-last line?[/color]
                How[color=blue]
                > can a "declaratio n" have an "initialize r equal to 0" (or behave "as if" it
                > had one) without being considered "the definition" of the object across[/color]
                all[color=blue]
                > TU's? I don't know.[/color]

                I don't think it can - that's the point. I guess they avoided "definition "
                since this is the section that's defining "definition ".
                [color=blue]
                > Note that this is not within a constraints section, and therefore whatever
                > it means, the compiler is not obliged to produce a diagnostic if it is
                > violated. So it could in fact be saying that there's only supposed to be
                > one, but if an implementation carries the "tentativen ess" over to the link
                > phase, and it works as someone would expect it to (or be used to it[/color]
                working[color=blue]
                > from a historical basis), that isn't necessarily a non-conforming
                > implementation.[/color]

                I think it just means that it results in undefined behaviour. The
                pre-standard compilers that implemented the 'common model' can continue
                to do so, and other compilers don't have to do anything in particular.



                Comment

                • J. J. Farrell

                  #9
                  Re: External object definition and linkage


                  "Eric Sosman" <Eric.Sosman@su n.com> wrote in message
                  news:406DF7D6.8 719DE16@sun.com ...[color=blue]
                  > "J. J. Farrell" wrote:[color=green]
                  > >
                  > > After many years of dealing with definition and linkage issues
                  > > in ways that I know to be safe, I've decided it's time to try
                  > > to understand this area properly. Consider a header file with
                  > > the file scope declaration
                  > >
                  > > int i;
                  > >
                  > > This header is included in two files that refer to i but do not
                  > > declare it. The two files build together into a single program.
                  > >
                  > > i is therefore declared once in each translation unit. According
                  > > to C99 6.2.2 the declarations have external linkage and refer to
                  > > the same object. 6.9.2 says that each declaration is a tentative
                  > > external definition, which then gets converted to an actual
                  > > external definition. There are now 2 external definitions of i
                  > > in the program, which breaks the requirement in 6.9 that there
                  > > shall be exactly one external definition, so this results in
                  > > undefined behavior.
                  > >
                  > > Have I got this right? Confirmation or correction appreciated.[/color]
                  >
                  > You're right.[/color]

                  Thanks.
                  [color=blue]
                  > The usual practice (for any externally-linked object or
                  > function) is to put a declaration, not a definition, in a
                  > header file, and to #include that header wherever it's needed.
                  > The actual definition goes in one and only one .c file, which
                  > itself also #include's the header (so the compiler can complain
                  > if the declaration and the definition disagree).[/color]

                  Indeed. An alternative to avoid listing all the variables in
                  two places is for the header to contain something like

                  #if defined(DEFINE_ GLOBALS)
                  #define EXTDECL
                  #else
                  #define EXTDECL extern
                  #endif
                  EXTDECL char global;

                  and then define DEFINE_GLOBALS in exactly one .c file before
                  including the header. Not exactly elegant, but it avoids
                  duplicating a list of variables, and avoids all the bugs that
                  come from not getting the duplication right and up to date.

                  The aim of this exercise was to make sure I understood if any
                  other ways of doing it are valid, and to be able to give a
                  better answer than "because I said so" or "because that's what
                  the Standard says" when people don't believe that that's the
                  only right way to do it.



                  Comment

                  • J. J. Farrell

                    #10
                    Re: External object definition and linkage


                    "Eric Sosman" <Eric.Sosman@su n.com> wrote in message
                    news:406DF7D6.8 719DE16@sun.com ...[color=blue]
                    > "J. J. Farrell" wrote:[color=green]
                    > >
                    > > After many years of dealing with definition and linkage issues
                    > > in ways that I know to be safe, I've decided it's time to try
                    > > to understand this area properly. Consider a header file with
                    > > the file scope declaration
                    > >
                    > > int i;
                    > >
                    > > This header is included in two files that refer to i but do not
                    > > declare it. The two files build together into a single program.
                    > >
                    > > i is therefore declared once in each translation unit. According
                    > > to C99 6.2.2 the declarations have external linkage and refer to
                    > > the same object. 6.9.2 says that each declaration is a tentative
                    > > external definition, which then gets converted to an actual
                    > > external definition. There are now 2 external definitions of i
                    > > in the program, which breaks the requirement in 6.9 that there
                    > > shall be exactly one external definition, so this results in
                    > > undefined behavior.
                    > >
                    > > Have I got this right? Confirmation or correction appreciated.[/color]
                    >
                    > You're right.[/color]

                    Thanks.
                    [color=blue]
                    > The usual practice (for any externally-linked object or
                    > function) is to put a declaration, not a definition, in a
                    > header file, and to #include that header wherever it's needed.
                    > The actual definition goes in one and only one .c file, which
                    > itself also #include's the header (so the compiler can complain
                    > if the declaration and the definition disagree).[/color]

                    Indeed. An alternative to avoid listing all the variables in
                    two places is for the header to contain something like

                    #if defined(DEFINE_ GLOBALS)
                    #define EXTDECL
                    #else
                    #define EXTDECL extern
                    #endif
                    EXTDECL char global;

                    and then define DEFINE_GLOBALS in exactly one .c file before
                    including the header. Not exactly elegant, but it avoids
                    duplicating a list of variables, and avoids all the bugs that
                    come from not getting the duplication right and up to date.

                    The aim of this exercise was to make sure I understood if any
                    other ways of doing it are valid, and to be able to give a
                    better answer than "because I said so" or "because that's what
                    the Standard says" when people don't believe that that's the
                    only right way to do it.



                    Comment

                    • J. J. Farrell

                      #11
                      Re: External object definition and linkage


                      "CBFalconer " <cbfalconer@yah oo.com> wrote in message
                      news:406E9CBD.7 EE3D7E3@yahoo.c om...[color=blue]
                      > CBFalconer wrote:[color=green]
                      > >
                      > > "J. J. Farrell" wrote:[color=darkred]
                      > > >
                      > > > After many years of dealing with definition and linkage issues
                      > > > in ways that I know to be safe, I've decided it's time to try
                      > > > to understand this area properly. Consider a header file with
                      > > > the file scope declaration
                      > > >
                      > > > int i;
                      > > >
                      > > > This header is included in two files that refer to i but do not
                      > > > declare it. The two files build together into a single program.[/color]
                      > >
                      > > and is thus a mistake. You omitted the word "extern".
                      > >[color=darkred]
                      > > >
                      > > > i is therefore declared once in each translation unit. According
                      > > > to C99 6.2.2 the declarations have external linkage and refer to
                      > > > the same object. 6.9.2 says that each declaration is a tentative
                      > > > external definition, which then gets converted to an actual
                      > > > external definition. There are now 2 external definitions of i
                      > > > in the program, which breaks the requirement in 6.9 that there
                      > > > shall be exactly one external definition, so this results in
                      > > > undefined behavior.
                      > > >
                      > > > Have I got this right? Confirmation or correction appreciated.[/color]
                      > >
                      > > No. Header files should only specify the exposure of elements in
                      > > the source. They should not declare any data or functions.[/color]
                      >
                      > Quick, change that 'declare' to 'define', before the rats get at
                      > it.[/color]

                      Thanks Chuck, but I'm confused by the "no". Are you saying it's not
                      undefined behaviour, or that it is undefined behaviour but my reasons
                      why are wrong, or something else?



                      Comment

                      • J. J. Farrell

                        #12
                        Re: External object definition and linkage


                        "CBFalconer " <cbfalconer@yah oo.com> wrote in message
                        news:406E9CBD.7 EE3D7E3@yahoo.c om...[color=blue]
                        > CBFalconer wrote:[color=green]
                        > >
                        > > "J. J. Farrell" wrote:[color=darkred]
                        > > >
                        > > > After many years of dealing with definition and linkage issues
                        > > > in ways that I know to be safe, I've decided it's time to try
                        > > > to understand this area properly. Consider a header file with
                        > > > the file scope declaration
                        > > >
                        > > > int i;
                        > > >
                        > > > This header is included in two files that refer to i but do not
                        > > > declare it. The two files build together into a single program.[/color]
                        > >
                        > > and is thus a mistake. You omitted the word "extern".
                        > >[color=darkred]
                        > > >
                        > > > i is therefore declared once in each translation unit. According
                        > > > to C99 6.2.2 the declarations have external linkage and refer to
                        > > > the same object. 6.9.2 says that each declaration is a tentative
                        > > > external definition, which then gets converted to an actual
                        > > > external definition. There are now 2 external definitions of i
                        > > > in the program, which breaks the requirement in 6.9 that there
                        > > > shall be exactly one external definition, so this results in
                        > > > undefined behavior.
                        > > >
                        > > > Have I got this right? Confirmation or correction appreciated.[/color]
                        > >
                        > > No. Header files should only specify the exposure of elements in
                        > > the source. They should not declare any data or functions.[/color]
                        >
                        > Quick, change that 'declare' to 'define', before the rats get at
                        > it.[/color]

                        Thanks Chuck, but I'm confused by the "no". Are you saying it's not
                        undefined behaviour, or that it is undefined behaviour but my reasons
                        why are wrong, or something else?



                        Comment

                        • Irrwahn Grausewitz

                          #13
                          Re: External object definition and linkage

                          "J. J. Farrell" <jjf@bcs.org.uk > wrote:

                          <snip>
                          [color=blue]
                          >Indeed. An alternative to avoid listing all the variables in
                          >two places is for the header to contain something like
                          >
                          >#if defined(DEFINE_ GLOBALS)
                          >#define EXTDECL
                          >#else
                          >#define EXTDECL extern
                          >#endif
                          >EXTDECL char global;[/color]

                          This is however a bad chosen example, since macros that begin
                          with E followed by a digit or an uppercase letter are reserved
                          for future library extensions.

                          Regards
                          --
                          Irrwahn Grausewitz (irrwahn33@free net.de)
                          welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
                          clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
                          clc OT guide : http://benpfaff.org/writings/clc/off-topic.html

                          Comment

                          • Irrwahn Grausewitz

                            #14
                            Re: External object definition and linkage

                            "J. J. Farrell" <jjf@bcs.org.uk > wrote:

                            <snip>
                            [color=blue]
                            >Indeed. An alternative to avoid listing all the variables in
                            >two places is for the header to contain something like
                            >
                            >#if defined(DEFINE_ GLOBALS)
                            >#define EXTDECL
                            >#else
                            >#define EXTDECL extern
                            >#endif
                            >EXTDECL char global;[/color]

                            This is however a bad chosen example, since macros that begin
                            with E followed by a digit or an uppercase letter are reserved
                            for future library extensions.

                            Regards
                            --
                            Irrwahn Grausewitz (irrwahn33@free net.de)
                            welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
                            clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
                            clc OT guide : http://benpfaff.org/writings/clc/off-topic.html

                            Comment

                            • CBFalconer

                              #15
                              Re: External object definition and linkage

                              "J. J. Farrell" wrote:[color=blue]
                              > "CBFalconer " <cbfalconer@yah oo.com> wrote in message[color=green]
                              >> CBFalconer wrote:[color=darkred]
                              >>> "J. J. Farrell" wrote:
                              >>>>
                              >>>> After many years of dealing with definition and linkage issues
                              >>>> in ways that I know to be safe, I've decided it's time to try
                              >>>> to understand this area properly. Consider a header file with
                              >>>> the file scope declaration
                              >>>>
                              >>>> int i;
                              >>>>
                              >>>> This header is included in two files that refer to i but do not
                              >>>> declare it. The two files build together into a single program.
                              >>>
                              >>> and is thus a mistake. You omitted the word "extern".
                              >>>
                              >>>>
                              >>>> i is therefore declared once in each translation unit. According
                              >>>> to C99 6.2.2 the declarations have external linkage and refer to
                              >>>> the same object. 6.9.2 says that each declaration is a tentative
                              >>>> external definition, which then gets converted to an actual
                              >>>> external definition. There are now 2 external definitions of i
                              >>>> in the program, which breaks the requirement in 6.9 that there
                              >>>> shall be exactly one external definition, so this results in
                              >>>> undefined behavior.
                              >>>>
                              >>>> Have I got this right? Confirmation or correction appreciated.
                              >>>
                              >>> No. Header files should only specify the exposure of elements in
                              >>> the source. They should not declare any data or functions.[/color]
                              >>
                              >> Quick, change that 'declare' to 'define', before the rats get at
                              >> it.[/color]
                              >
                              > Thanks Chuck, but I'm confused by the "no". Are you saying it's
                              > not undefined behaviour, or that it is undefined behaviour but my
                              > reasons why are wrong, or something else?[/color]

                              No, you haven't got it right.

                              --
                              A: Because it fouls the order in which people normally read text.
                              Q: Why is top-posting such a bad thing?
                              A: Top-posting.
                              Q: What is the most annoying thing on usenet and in e-mail?


                              Comment

                              Working...