Help wanted on some source codes

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

    #1

    Help wanted on some source codes

    1.============= =============== ===============
    /* a.c */
    int x;
    int y;

    void main()
    {
    f();
    printf("%x %x\n", x, y);
    }

    /* b.c */
    double x;

    void f()
    {
    x = -0.0;
    }


    2.============= =============== ===============
    /* a.c */
    int x = 1;
    int y;

    void main()
    {
    f();
    printf("%x %x\n", x, y);
    }

    /* b.c */
    double x;

    void f()
    {
    x = -0.0;
    }

    3.============= =============== ===============
    /* a.c */
    int x;
    int y = 1;

    void main()
    {
    f();
    printf("%x %x\n", x, y);
    }

    /* b.c */
    double x;

    void f()
    {
    x = -0.0;
    }

    4.============= =============== ===============
    /* a.c */
    int x = 1;
    int y = 1;

    void main()
    {
    f();
    printf("%x %x\n", x, y);
    }

    /* b.c */
    double x;

    void f()
    {
    x = -0.0;
    }

    5.============= =============== ===============
    /* a.c */
    int x = 1;
    int y = 1;

    void main()
    {
    f();
    printf("%x %x\n", x, y);
    }

    /* b.c */
    double x;

    void f()
    {
    x = -0;
    }


    Remark========= =============== ===============
    The above programs from 1 to 5 are all constituted
    of two separate files, a.c & b.c, and can be
    compiled under gcc.
    e.g.
    /* Linux */
    $ gcc -o test a.c b.c
    $ ./test
    /* Windows */
    C:\gcc -o test.exe a.c b.c
    C:\test


    Question======= =============== =============== ==
    I'm wondering about the strange results generated
    by the programs. Please help me. I want to understand
    why the results are like that.
    By the way, the source codes above are in old K&R style
    and will be warned by the gcc, you can change them to
    new ISO/ANSI style :-)

    Thanks in advance & best regards!

    Becker
    30-Nov-2005

  • Walter Roberson

    #2
    Re: Help wanted on some source codes

    In article <1133311547.679 305.247520@z14g 2000cwz.googleg roups.com>,
    Becker <webmaster@devh r.com> wrote:[color=blue]
    >1.============ =============== =============== =
    >/* a.c */
    >int x;
    >int y;
    >
    >void main()
    >{
    > f();
    > printf("%x %x\n", x, y);
    >}[/color]

    %x expects an unsigned int, not an int.
    [color=blue]
    >/* b.c */
    >double x;
    >
    >void f()
    >{
    > x = -0.0;
    >}[/color]

    You never initialize y at all, and you initialize x to the wrong
    type. double might or might not be the same size as int; it is not
    uncommon for it to be longer, but that is not certain. If it is longer
    then you -might- end up overwritting y, but the relative order of x and
    y are not fixed by the standard, and double might be larger than two
    ints together so you might be scribbling on a random portion of memory.

    If you happen to be using IEEE754 floating point, then -0.0 is
    considered to be different than 0.0 . Even on systems that it is not,
    the floating point representation of 0 is not certain to be all binary
    0's (though -some- floating point standards require that all-binary 0's
    must be treated as floating point 0.)

    Your programs 2 thru 4 are just variations on exactly the same themes
    with various different values initializing the memory that might or might
    not be scribbled over.

    [color=blue]
    >5.============ =============== =============== =[/color]
    [color=blue]
    >void f()
    >{
    > x = -0;
    >}[/color]

    -0 is an integer constant, and it is the same as 0 on all but the
    rather-uncommon signed-magnitude machines (which are allowed for by
    the standard.) -0 as an integer is thus the same as 0 as an integer.
    That integer is then cast to the double that you have declared x to
    be in this file. On some systems that is different than the floating
    point -0.0 .
    --
    "It is important to remember that when it comes to law, computers
    never make copies, only human beings make copies. Computers are given
    commands, not permission. Only people can be given permission."
    -- Brad Templeton

    Comment

    • Old Wolf

      #3
      Re: Help wanted on some source codes

      Becker wrote:
      [color=blue]
      > 1.============= =============== ===============
      > /* a.c */
      > int x;
      > int y;
      >
      > void main()
      > {
      > f();
      > printf("%x %x\n", x, y);
      > }
      >
      > /* b.c */
      > double x;
      >
      > void f()
      > {
      > x = -0.0;
      > }[/color]

      All of your programs have undefined behaviour because there
      are two variables called 'x' with external linkage.

      Also, "%x" is only to be used for unsigned ints, and
      main should return an int (allowing "void main" is compiler-
      specific).

      For an understanding of why GCC gives the results you see,
      please ask your question on a GCC newsgroup.

      Comment

      • slebetman@yahoo.com

        #4
        Re: Help wanted on some source codes

        Old Wolf wrote:[color=blue]
        > Becker wrote:
        >[color=green]
        > > 1.============= =============== ===============
        > > /* a.c */
        > > int x;
        > > int y;
        > >
        > > void main()
        > > {
        > > f();
        > > printf("%x %x\n", x, y);
        > > }
        > >
        > > /* b.c */
        > > double x;
        > >
        > > void f()
        > > {
        > > x = -0.0;
        > > }[/color]
        >
        > All of your programs have undefined behaviour because there
        > are two variables called 'x' with external linkage.
        >[/color]

        The programs are rubbish of course. But wouldn't the file scope of x
        mean that function f() is actually refering to the double x instead of
        the int x?

        Comment

        • Jack Klein

          #5
          Re: Help wanted on some source codes

          On 29 Nov 2005 16:45:47 -0800, "Becker" <webmaster@devh r.com> wrote in
          comp.lang.c:
          [color=blue]
          > 1.============= =============== ===============
          > /* a.c */
          > int x;
          > int y;
          >
          > void main()
          > {
          > f();
          > printf("%x %x\n", x, y);
          > }
          >
          > /* b.c */
          > double x;
          >
          > void f()
          > {
          > x = -0.0;
          > }[/color]

          [snip several other examples]

          Each of your examples defines main() with a return type of void, and
          also has main() call a function without a declaration in scope. There
          is no version of the C standard where a program performing both of
          these actions is legal.

          If you are using gcc as a standard compiler conforming to the C
          standard prior to 1999, 'void main()' invokes undefined behavior
          immediately. Friends don't let friends void main(). If you are using
          gcc as a standard compiler conforming to a 1999 or later version of
          the C standard, it is a constraint violation to call a function
          without a declaration in scope.

          So you are not invoking gcc to conform to any version of the C
          standard, which is just as well, because your program is not actually
          valid C.

          But as to the question you asked, even if you fixed these things:

          Each of your examples defines 'x' with external linkage in two
          different source files. It doesn't even make any difference whether
          'x' has the same type or different types in the two definitions, you
          have broken a rule and have undefined behavior.

          Once you have undefined behavior, it's "game over, thanks for playing,
          Carol will give you some lovely parting gifts". The C language
          neither knows or cares what happens next, there is no right or wrong.
          It could cause the CD drive tray to jump out and hit you in the nose.
          Even if the computer does not have a CD drive.

          The C standard says this in "6.9 External definitions" paragraph 5:

          "An external definition is an external declaration that is also a
          definition of a function (other than an inline definition) or an
          object. If an identifier declared with external linkage is used in an
          expression (other than as part of the operand of a sizeof operator
          whose result is an integer constant), somewhere in the entire program
          there shall be exactly one external definition for the identifier;
          otherwise, there shall be no more than one."

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

          • Jack Klein

            #6
            Re: Help wanted on some source codes

            On 29 Nov 2005 18:34:15 -0800, "slebetman@yaho o.com"
            <slebetman@gmai l.com> wrote in comp.lang.c:
            [color=blue]
            > Old Wolf wrote:[color=green]
            > > Becker wrote:
            > >[color=darkred]
            > > > 1.============= =============== ===============
            > > > /* a.c */
            > > > int x;
            > > > int y;
            > > >
            > > > void main()
            > > > {
            > > > f();
            > > > printf("%x %x\n", x, y);
            > > > }
            > > >
            > > > /* b.c */
            > > > double x;
            > > >
            > > > void f()
            > > > {
            > > > x = -0.0;
            > > > }[/color]
            > >
            > > All of your programs have undefined behaviour because there
            > > are two variables called 'x' with external linkage.
            > >[/color]
            >
            > The programs are rubbish of course. But wouldn't the file scope of x
            > mean that function f() is actually refering to the double x instead of
            > the int x?[/color]

            This is part of what I posted in a reply to the OP, but I'll repeat it
            here for your benefit. The issue here is NOT file scope, but most
            specifically IS external linkage:

            The C standard says this in "6.9 External definitions" paragraph 5:

            "An external definition is an external declaration that is also a
            definition of a function (other than an inline definition) or an
            object. If an identifier declared with external linkage is used in an
            expression (other than as part of the operand of a sizeof operator
            whose result is an integer constant), somewhere in the entire program
            there shall be exactly one external definition for the identifier;
            otherwise, there shall be no more than one."

            Violating a 'shall' outside of a constraint section is just plain old
            ordinary undefined behavior. You have left planet C behind and
            entered the Twilight Zone, and there is no right or wrong.

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


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

            • Skarmander

              #7
              Re: Help wanted on some source codes

              slebetman@yahoo .com wrote:[color=blue]
              > Old Wolf wrote:[color=green]
              >> Becker wrote:
              >>[color=darkred]
              >>> 1.============= =============== ===============
              >>> /* a.c */
              >>> int x;
              >>> int y;
              >>>
              >>> void main()
              >>> {
              >>> f();
              >>> printf("%x %x\n", x, y);
              >>> }
              >>>
              >>> /* b.c */
              >>> double x;
              >>>
              >>> void f()
              >>> {
              >>> x = -0.0;
              >>> }[/color]
              >> All of your programs have undefined behaviour because there
              >> are two variables called 'x' with external linkage.
              >>[/color]
              >
              > The programs are rubbish of course. But wouldn't the file scope of x
              > mean that function f() is actually refering to the double x instead of
              > the int x?
              >[/color]
              Nope, because technically, there's no difference between the two.

              First of all, this program is in violation of:

              6.9-5 "If an identifier declared with external linkage is used in an
              expression [..], somewhere in the entire program there shall be exactly one
              external definition for the identifier; [..]"

              But suppose one of these was an "extern" declaration instead, so there was
              only one definition. Then we get:

              6.2.2-2 "In the set of translation units and libraries that constitutes an
              entire program, each declaration of a particular identifier with external
              linkage denotes the same object or function."

              So the "int x" and "double x" must be the same object. But of course that's
              not possible, and we are violating:

              6.2.7-2 "All declarations that refer to the same object or function shall
              have compatible type; otherwise, the behavior is undefined."

              Needless to say, int and double are not compatible types.

              Now, in *practice*, a compiler will indeed treat the 'x' in a.c and the 'x'
              in b.c as different objects within their respective scopes, compile the
              units as such, and then the linker will either notice a conflict (best
              case), create two separate objects (suboptimal but not completely awful
              case), or not notice anything at all and happily merge the storage for these
              incompatible objects (worst but unfortunately also most likely case).

              Try this: assign some nontrivial value to 'x' in 'f', try to compile and
              link the program, then run it if this works. You should see the value of the
              double (partially) reinterpreted as an int. Say hi to the nasal demons for
              me when you do this.

              This notwithstanding , a platform would actually be allowed to format your
              harddisk immediately after parsing both a.c and b.c, without paying any
              consideration to scope. The behavior is undefined; scope is irrelevant.

              S.

              Comment

              • slebetman@yahoo.com

                #8
                Re: Help wanted on some source codes

                Jack Klein wrote:[color=blue]
                > On 29 Nov 2005 18:34:15 -0800, "slebetman@yaho o.com"
                > <slebetman@gmai l.com> wrote in comp.lang.c:[color=green]
                > > The programs are rubbish of course. But wouldn't the file scope of x
                > > mean that function f() is actually refering to the double x instead of
                > > the int x?[/color]
                >
                > This is part of what I posted in a reply to the OP, but I'll repeat it
                > here for your benefit. The issue here is NOT file scope, but most
                > specifically IS external linkage:
                >
                > The C standard says this in "6.9 External definitions" paragraph 5:
                >
                > "An external definition is an external declaration that is also a
                > definition of a function (other than an inline definition) or an
                > object. If an identifier declared with external linkage is used in an
                > expression (other than as part of the operand of a sizeof operator
                > whose result is an integer constant), somewhere in the entire program
                > there shall be exactly one external definition for the identifier;
                > otherwise, there shall be no more than one."
                >
                > Violating a 'shall' outside of a constraint section is just plain old
                > ordinary undefined behavior. You have left planet C behind and
                > entered the Twilight Zone, and there is no right or wrong.
                >[/color]

                Yes I understand that. But I didn't think all globals are external
                linkage by default. I thought you need to use the 'extern' keyword for
                that. So, without extern globals with the same name have undefined
                behavior? I'm guessing that globals declared with the 'static' keyword
                can have the same name.

                Comment

                • Richard Heathfield

                  #9
                  Re: Help wanted on some source codes

                  slebetman@yahoo .com said:
                  [color=blue]
                  > But I didn't think all globals are external
                  > linkage by default. I thought you need to use the 'extern' keyword for
                  > that.[/color]

                  No. When you do this:

                  extern int foo;

                  you are saying "dear compiler, I promise to you that there is an object
                  called foo, which is an int, but its storage is already reserved elsewhere
                  so you don't need to reserve any; just trust me on this". Each translation
                  unit needing to read or write foo (EXCEPT ONE) will need to have such a
                  line. Typically, such lines are put into a header.

                  In exactly one place in your program (at file scope), you must keep your
                  promise:

                  int foo;

                  The translation unit that has this line need not have an extern int foo; as
                  well (although it will do no harm if it does).

                  --
                  Richard Heathfield
                  "Usenet is a strange place" - dmr 29/7/1999

                  email: rjh at above domain (but drop the www, obviously)

                  Comment

                  • slebetman@yahoo.com

                    #10
                    Re: Help wanted on some source codes

                    Richard Heathfield wrote:[color=blue]
                    > slebetman@yahoo .com said:
                    >[color=green]
                    > > But I didn't think all globals are external
                    > > linkage by default. I thought you need to use the 'extern' keyword for
                    > > that.[/color]
                    >
                    > No. When you do this:
                    >
                    > extern int foo;
                    >
                    > you are saying "dear compiler, I promise to you that there is an object
                    > called foo, which is an int, but its storage is already reserved elsewhere
                    > so you don't need to reserve any; just trust me on this". Each translation
                    > unit needing to read or write foo (EXCEPT ONE) will need to have such a
                    > line. Typically, such lines are put into a header.
                    >
                    > In exactly one place in your program (at file scope), you must keep your
                    > promise:
                    >
                    > int foo;
                    >
                    > The translation unit that has this line need not have an extern int foo; as
                    > well (although it will do no harm if it does).
                    >[/color]

                    Ah yes, quite right. Extern merely means "it's somewhere else" not
                    "please export this". Thank you for reminding me.

                    Comment

                    • Becker

                      #11
                      Re: Help wanted on some source codes

                      Thanks all :-)
                      Yes, I understand now. The codes are full of undifined behaviors.
                      And If I want to know why the results are like that, I should
                      get to know how gcc treats those "undifined behaviors".

                      PS: I get those programs from a forum :-P

                      Comment

                      • Allin Cottrell

                        #12
                        Re: Help wanted on some source codes

                        Jack Klein wrote:
                        [color=blue]
                        > Friends don't let friends void main().[/color]

                        I like it! Looks like sig material to me.

                        Allin Cottrell

                        Comment

                        • Flash Gordon

                          #13
                          Re: Help wanted on some source codes

                          slebetman@yahoo .com wrote:[color=blue]
                          > Old Wolf wrote:[color=green]
                          >> Becker wrote:
                          >>[color=darkred]
                          >>> 1.============= =============== ===============
                          >>> /* a.c */
                          >>> int x;
                          >>> int y;
                          >>>
                          >>> void main()
                          >>> {
                          >>> f();
                          >>> printf("%x %x\n", x, y);
                          >>> }
                          >>>
                          >>> /* b.c */
                          >>> double x;
                          >>>
                          >>> void f()
                          >>> {
                          >>> x = -0.0;
                          >>> }[/color]
                          >> All of your programs have undefined behaviour because there
                          >> are two variables called 'x' with external linkage.[/color]
                          >
                          > The programs are rubbish of course. But wouldn't the file scope of x
                          > mean that function f() is actually refering to the double x instead of
                          > the int x?[/color]

                          No, both variable x have external linkage therefore the behaviour is
                          undefined and on some systems, with some options, won't even link. If it
                          does link the compiler is allowed to put both items in the same
                          location, make that location the size of the smaller (probably int) and
                          send a letter to you mother telling her you are dead. Alternatively the
                          compiler/linker could place the two variables in separate locations and
                          send a letter to the accounts department of the company you work for
                          telling them to stop your salary. Anything it does is valid.
                          --
                          Flash Gordon
                          Living in interesting times.
                          Although my email address says spam, it is real and I read it.

                          Comment

                          • Becker

                            #14
                            Re: Help wanted on some source codes


                            Flash Gordon wrote:[color=blue]
                            >
                            > No, both variable x have external linkage therefore the behaviour is
                            > undefined and on some systems, with some options, won't even link. If it
                            > does link the compiler is allowed to put both items in the same
                            > location, make that location the size of the smaller (probably int) and
                            > send a letter to you mother telling her you are dead. Alternatively the
                            > compiler/linker could place the two variables in separate locations and
                            > send a letter to the accounts department of the company you work for
                            > telling them to stop your salary. Anything it does is valid.
                            > --
                            > Flash Gordon
                            > Living in interesting times.
                            > Although my email address says spam, it is real and I read it.[/color]

                            hehe, I got it.

                            Comment

                            Working...