Why no compilation error.

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

    Why no compilation error.

    We have three files a.c, b.c and main.c respectively as follows:
    a.c
    ---
    int a;
    b.c
    ---
    int a = 10;
    main.c
    ------
    extern int a;
    int main()
    {
    printf("a = %d\n",a);
    return 0;
    }
    Let's see what happens, when the files are compiled together:
    bash$ gcc a.c b.c main.c
    bash$ ./a.out
    a = 10
    Hmm!! no compilation/linker error!!! Why is it so??

  • Jack Klein

    #2
    Re: Why no compilation error.

    On 19 Sep 2006 22:12:12 -0700, "sunny" <sunny.nls@gmai l.comwrote in
    comp.lang.c:
    We have three files a.c, b.c and main.c respectively as follows:
    a.c
    ---
    int a;
    b.c
    ---
    int a = 10;
    main.c
    ------
    extern int a;
    int main()
    {
    printf("a = %d\n",a);
    return 0;
    }
    Let's see what happens, when the files are compiled together:
    bash$ gcc a.c b.c main.c
    bash$ ./a.out
    a = 10
    Hmm!! no compilation/linker error!!! Why is it so??
    Your program produces undefined behavior by having more than one
    definition of an external object. The compiler is free to do anything
    it wants. Once you generate undefined behavior, the C language no
    longer places any requirements on the results.

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

    Comment

    • deepak

      #3
      Re: Why no compilation error.

      Can anyone give a nice link of how these example works?

      Jack Klein wrote:
      On 19 Sep 2006 22:12:12 -0700, "sunny" <sunny.nls@gmai l.comwrote in
      comp.lang.c:
      >
      We have three files a.c, b.c and main.c respectively as follows:
      a.c
      ---
      int a;
      b.c
      ---
      int a = 10;
      main.c
      ------
      extern int a;
      int main()
      {
      printf("a = %d\n",a);
      return 0;
      }
      Let's see what happens, when the files are compiled together:
      bash$ gcc a.c b.c main.c
      bash$ ./a.out
      a = 10
      Hmm!! no compilation/linker error!!! Why is it so??
      >
      Your program produces undefined behavior by having more than one
      definition of an external object. The compiler is free to do anything
      it wants. Once you generate undefined behavior, the C language no
      longer places any requirements on the results.
      >
      --
      Jack Klein
      Home: http://JK-Technology.Com
      FAQs for
      comp.lang.c http://c-faq.com/
      comp.lang.c++ http://www.parashift.com/c++-faq-lite/
      alt.comp.lang.l earn.c-c++
      http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html

      Comment

      • Peter Nilsson

        #4
        Re: Why no compilation error.

        Jack Klein wrote:
        "sunny" <sunny.nls@gmai l.comwrote in comp.lang.c:
        We have three files a.c, b.c and main.c respectively as follows:
        a.c
        ---
        int a;
        b.c
        ---
        int a = 10;
        main.c
        ------
        extern int a;
        int main()
        {
        printf("a = %d\n",a);
        return 0;
        }
        Let's see what happens, when the files are compiled together:
        bash$ gcc a.c b.c main.c
        Note: gcc has not been invoked as a conforming compiler, so you
        can't have any expectations under the C language standard.
        bash$ ./a.out
        a = 10
        Hmm!! no compilation/linker error!!! Why is it so??
        >
        Your program produces undefined behavior by having more than one
        definition of an external object. The compiler is free to do anything
        it wants. Once you generate undefined behavior, the C language no
        longer places any requirements on the results.
        Or, to more accurately answer the OP's question, the behaviour is UB
        by 6.9p5, however that paragraph is not one of the listed Contraints
        for 6.9 [pp2-3], so no diagnostic is required.

        Why it's not a constraint, I don't know.

        --
        Peter

        Comment

        • Harald van Dijk

          #5
          Re: Why no compilation error.

          Peter Nilsson wrote:
          Jack Klein wrote:
          "sunny" <sunny.nls@gmai l.comwrote in comp.lang.c:
          We have three files a.c, b.c and main.c respectively as follows:
          a.c
          ---
          int a;
          b.c
          ---
          int a = 10;
          main.c
          ------
          extern int a;
          int main()
          {
          printf("a = %d\n",a);
          return 0;
          }
          Let's see what happens, when the files are compiled together:
          bash$ gcc a.c b.c main.c
          >
          Note: gcc has not been invoked as a conforming compiler, so you
          can't have any expectations under the C language standard.
          >
          bash$ ./a.out
          a = 10
          Hmm!! no compilation/linker error!!! Why is it so??
          Your program produces undefined behavior by having more than one
          definition of an external object. The compiler is free to do anything
          it wants. Once you generate undefined behavior, the C language no
          longer places any requirements on the results.
          >
          Or, to more accurately answer the OP's question, the behaviour is UB
          by 6.9p5, however that paragraph is not one of the listed Contraints
          for 6.9 [pp2-3], so no diagnostic is required.
          >
          Why it's not a constraint, I don't know.
          I imagine it's not a constraint because depending on the system, it may
          not have an easy way to tell this apart from a definition whose name
          matches that of a library function provided as an extension. In other
          words, it could also generate a diagnostic for this legitimate code:

          #include <stdio.h>
          void write(char *s) { puts(s); }
          int main(void) {
          write("Hello, world!");
          }

          Comment

          • sunny

            #6
            Re: Why no compilation error.

            Hi All
            but i get the compilation error if i initialize the variable "a" in a.c
            ie.
            // in a.c
            int a = 200;

            // in b.c
            int a = 10.

            on compilation, now i got multiple definition error.
            may on first i.e uninitialized "a" will be stored in BSS section and
            intialized "a" (a = 10) is stored in DS(data segment). so when i
            intialize "a" in a.c
            it will move to DS where it confilicts with "a" from b.c;

            is it correct?

            Peter Nilsson wrote:
            Jack Klein wrote:
            "sunny" <sunny.nls@gmai l.comwrote in comp.lang.c:
            We have three files a.c, b.c and main.c respectively as follows:
            a.c
            ---
            int a;
            b.c
            ---
            int a = 10;
            main.c
            ------
            extern int a;
            int main()
            {
            printf("a = %d\n",a);
            return 0;
            }
            Let's see what happens, when the files are compiled together:
            bash$ gcc a.c b.c main.c
            >
            Note: gcc has not been invoked as a conforming compiler, so you
            can't have any expectations under the C language standard.
            >
            bash$ ./a.out
            a = 10
            Hmm!! no compilation/linker error!!! Why is it so??
            Your program produces undefined behavior by having more than one
            definition of an external object. The compiler is free to do anything
            it wants. Once you generate undefined behavior, the C language no
            longer places any requirements on the results.
            >
            Or, to more accurately answer the OP's question, the behaviour is UB
            by 6.9p5, however that paragraph is not one of the listed Contraints
            for 6.9 [pp2-3], so no diagnostic is required.
            >
            Why it's not a constraint, I don't know.
            >
            --
            Peter

            Comment

            • Jack Klein

              #7
              Re: Why no compilation error.

              On 19 Sep 2006 23:59:33 -0700, "sunny" <sunny.nls@gmai l.comwrote in
              comp.lang.c:
              Hi All
              but i get the compilation error if i initialize the variable "a" in a.c
              ie.
              // in a.c
              int a = 200;
              >
              // in b.c
              int a = 10.
              >
              on compilation, now i got multiple definition error.
              may on first i.e uninitialized "a" will be stored in BSS section and
              intialized "a" (a = 10) is stored in DS(data segment). so when i
              intialize "a" in a.c
              it will move to DS where it confilicts with "a" from b.c;
              >
              is it correct?
              It is not correct. It is not incorrect. Once you produce undefined
              behavior, the C standard no longer specifies what the program must do.
              As far as the C language is concerned, anything that happens is just
              as correct or incorrect as anything else.

              You have broken a rule of C programming. Don't do that. Then you
              won't have to worry whether what happens is correct.

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

              Comment

              • Jean-Marc Bourguet

                #8
                Re: Why no compilation error.

                "sunny" <sunny.nls@gmai l.comwrites:
                We have three files a.c, b.c and main.c respectively as follows:
                a.c
                ---
                int a;
                b.c
                ---
                int a = 10;
                main.c
                ------
                extern int a;
                int main()
                {
                printf("a = %d\n",a);
                return 0;
                }
                Let's see what happens, when the files are compiled together:
                bash$ gcc a.c b.c main.c
                bash$ ./a.out
                a = 10
                Hmm!! no compilation/linker error!!! Why is it so??
                >
                With gnu linker, use -Wl,--warn-common. That's the (sloppy) common unix
                practice.

                A+

                --
                Jean-Marc

                Comment

                • Amigo

                  #9
                  Re: Why no compilation error.

                  The variable is defined / initialised in two separate files. Each of
                  these C files will be compiled to object code. At the linking phase,
                  the linker usually has a specific order in which it searches for
                  external symbols, e.g. start with all the objects/libraries in current
                  folder in alphabetical order, followed by the so-called default paths
                  where other libraries and objects may reside. All the linkers I've
                  used, by default, will stop looking for an external reference if one
                  has already been found in an object or a library. Therefore, in this
                  case, it so happened that the linker encountered the definition with
                  initialisation first, hence the value 10 is displayed at execution. I
                  suppose a closer investigation of the linker properties would provide a
                  clear answer to this issue. Changing the initialisation from one file
                  to the other may exhibit a different behaviour (or at least I expect
                  to).

                  Romeo Ghiriti

                  Comment

                  • Amigo

                    #10
                    Re: Why no compilation error.

                    The variable is defined / initialised in two separate files. Each of
                    these C files will be compiled to object code. At the linking phase,
                    the linker usually has a specific order in which it searches for
                    external symbols, e.g. start with all the objects/libraries in current
                    folder in alphabetical order, followed by the so-called default paths
                    where other libraries and objects may reside. All the linkers I've
                    used, by default, will stop looking for an external reference if one
                    has already been found in an object or a library. Therefore, in this
                    case, it so happened that the linker encountered the definition with
                    initialisation first, hence the value 10 is displayed at execution. I
                    suppose a closer investigation of the linker properties would provide a
                    clear answer to this issue. Changing the initialisation from one file
                    to the other may exhibit a different behaviour (or at least I expect
                    to).

                    Romeo Ghiriti

                    Comment

                    • Default User

                      #11
                      Re: Why no compilation error. [TPA]

                      deepak wrote:
                      Can anyone give a nice link of how these example works?
                      Please don't top-post. Your replies belong following or interspersed
                      with properly trimmed quotes. See the majority of other posts in the
                      newsgroup, or:
                      <http://www.caliburn.nl/topposting.html >

                      Comment

                      • Default User

                        #12
                        Re: Why no compilation error. [TPA]

                        sunny wrote:
                        Hi All
                        Please don't top-post. Your replies belong following or interspersed
                        with properly trimmed quotes. See the majority of other posts in the
                        newsgroup, or:
                        <http://www.caliburn.nl/topposting.html >

                        Comment

                        • Christopher Benson-Manica

                          #13
                          Re: Why no compilation error. [TPA]

                          Default User <defaultuserbr@ yahoo.comwrote:
                          Please don't top-post.
                          Wouldn't the [TPA] be better placed at the beginning of the post title
                          rather than the end?

                          --
                          C. Benson Manica | I *should* know what I'm talking about - if I
                          cbmanica(at)gma il.com | don't, I need to know. Flames welcome.

                          Comment

                          • Jean-Marc Bourguet

                            #14
                            Re: Why no compilation error.

                            "Amigo" <rghiriti@hotma il.comwrites:
                            The variable is defined / initialised in two separate files. Each of
                            these C files will be compiled to object code. At the linking phase,
                            the linker usually has a specific order in which it searches for
                            external symbols, e.g. start with all the objects/libraries in current
                            folder in alphabetical order, followed by the so-called default paths
                            where other libraries and objects may reside. All the linkers I've
                            used, by default, will stop looking for an external reference if one
                            has already been found in an object or a library. Therefore, in this
                            case, it so happened that the linker encountered the definition with
                            initialisation first, hence the value 10 is displayed at execution. I
                            suppose a closer investigation of the linker properties would provide a
                            clear answer to this issue. Changing the initialisation from one file
                            to the other may exhibit a different behaviour (or at least I expect
                            to).
                            I think you are confusing two issues. A linker will not import an object
                            file if it doesn't provides some undefined symbol. (That's one way for
                            providing extensions in a library and still beeing able to use those
                            symbols in user programs; another way -- which is mandatory for dynamic
                            library which can't be broken into parts -- is to use something like elf's
                            weak symbols).

                            When the linker has decided that an object must be part of the image (and
                            all linkers I know consider that all object files directly given on the
                            command line are in that class), the linkers give error message for
                            duplicate definitions. Unix linker traditionnaly don't give such error
                            message when all but one of the definitions are tentative definitions.

                            Yours,

                            --
                            Jean-Marc

                            Comment

                            • Default User

                              #15
                              Re: Why no compilation error. [TPA]

                              Christopher Benson-Manica wrote:
                              Default User <defaultuserbr@ yahoo.comwrote:
                              >
                              Please don't top-post.
                              >
                              Wouldn't the [TPA] be better placed at the beginning of the post title
                              rather than the end?
                              Why? Where do I put it, before the "Re:"? Just after? I'm flexible, but
                              the end made more sense and is slightly easier to do, as it's easy it
                              position the cursor at the end accurately.

                              It's there so that people who want to filter can. The filter probably
                              doesn't care where it is.





                              Brian

                              Comment

                              Working...