K&R p 130

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

    #1

    K&R p 130

    Hi All,
    Just when I thought things were going to get easy!

    Structs.

    I **thought** I had copied the examples pretty closely, but am getting
    a number of errors.


    The code:
    >>>>>>
    #include <stdio.h>


    int main (int argc, const char * argv[]) {

    struct point {
    int x;
    int y;
    };


    struct point makepoint( int, int); /* error. previous decl of
    'makepoint' was here*/



    struct point p1 = makepoint(8,9);

    printf("%d, %d\n", p1.x, p1.y);
    }




    struct point makepoint(int x, int y) {
    struct point temp;
    temp.x = x;
    temp.y = y;
    return temp;
    }

    The error I got in the past has meant that something has been defined
    twice, but as far as I can tell, ( probably incorrectly) I have
    declared a struct called point, then declared a function which accepts
    two integer arguments and returns a 'point' structure. Clearly I am
    missing something.

    In addition, I am getting a number of errors in makepoint function
    defintion, which may become obvious once my initial query is cleared.
    If not, I will ask then.

    Lastly, K&R say , on p 130, of the makepoint function, "notice that
    there is no conflict between the argument name and the member with the
    same name". I assume that this refers to the lines

    temp.x = x;
    temp.y = y;

    Thanks as usual.



  • santosh

    #2
    Re: K&amp;R p 130

    mdh wrote:
    Hi All,
    Just when I thought things were going to get easy!
    >
    Structs.
    >
    I **thought** I had copied the examples pretty closely, but am getting
    a number of errors.
    >
    >
    The code:
    >
    >>>>>>>
    >
    #include <stdio.h>
    >
    >
    int main (int argc, const char * argv[]) {
    >
    struct point {
    int x;
    int y;
    };
    >
    >
    struct point makepoint( int, int); /* error. previous decl of
    'makepoint' was here*/
    >
    >
    >
    struct point p1 = makepoint(8,9);
    >
    printf("%d, %d\n", p1.x, p1.y);
    }
    >
    >
    >
    >
    struct point makepoint(int x, int y) {
    struct point temp;
    temp.x = x;
    temp.y = y;
    return temp;
    }
    >
    The error I got in the past has meant that something has been defined
    twice, but as far as I can tell, ( probably incorrectly) I have
    declared a struct called point, then declared a function which accepts
    two integer arguments and returns a 'point' structure. Clearly I am
    missing something.
    >
    In addition, I am getting a number of errors in makepoint function
    defintion, which may become obvious once my initial query is cleared.
    If not, I will ask then.
    >
    Lastly, K&R say , on p 130, of the makepoint function, "notice that
    there is no conflict between the argument name and the member with the
    same name". I assume that this refers to the lines
    >
    temp.x = x;
    temp.y = y;
    >
    Thanks as usual.
    Here's your code corrected:

    #include <stdio.h>

    struct point {
    int x;
    int y;
    };

    struct point makepoint( int, int);


    int main (void) {
    struct point p1 = makepoint(8,9);
    printf("%d, %d\n", p1.x, p1.y);
    return 0;

    }

    struct point makepoint(int x, int y) {
    struct point temp;
    temp.x = x;
    temp.y = y;
    return temp;
    }


    Comment

    • mdh

      #3
      Re: K&amp;R p 130

      On Aug 16, 11:12 pm, santosh <santosh....@gm ail.comwrote:
      >
      >
      Here's your code corrected:
      >
      #include <stdio.h>
      >
      struct point {
      int x;
      int y;
      >
      };
      >
      struct point makepoint( int, int);
      >
      snip
      }


      So I once again ran into a scope issue? In this case block scope? vs
      file scope which you implemented? Santosh, could you help me
      understand why I can declare 'int foo(int);' within "main" and then
      call it, but I cannot do the same with the struct?

      Comment

      • Malcolm McLean

        #4
        Re: K&amp;R p 130


        "mdh" <mdeh@comcast.n etwrote in message
        On Aug 16, 11:12 pm, santosh <santosh....@gm ail.comwrote:
        >
        >So I once again ran into a scope issue? In this case block scope? vs
        >file scope which you implemented? Santosh, could you help me
        >understand why I can declare 'int foo(int);' within "main" and then
        >call it, but I cannot do the same with the struct?
        >
        The struct is not local to main. It is used in another function.
        Similarly if you called foo() from anywhere except main(), you'd have to
        prototype it again.
        This is why we normally place structures and prototypes at the top of the
        file, usually wrapped up into a header.

        --
        Free games and programming goodies.


        Comment

        • =?GB2312?B?s8K35dHv?=

          #5
          Re: K&amp;R p 130

          On 8ÔÂ17ÈÕ, ÏÂÎç2ʱ25·Ö, mdh <m...@comcast.n etwrote:
          On Aug 16, 11:12 pm, santosh <santosh....@gm ail.comwrote:
          >
          >
          >
          >
          >
          Here's your code corrected:
          >
          #include <stdio.h>
          >
          struct point {
          int x;
          int y;
          >
          };
          >
          struct point makepoint( int, int);
          >
          snip
          }
          >
          So I once again ran into a scope issue? In this case block scope? vs
          file scope which you implemented? Santosh, could you help me
          understand why I can declare 'int foo(int);' within "main" and then
          call it, but I cannot do the same with the struct?
          The return type of 'int foo(int)' is "int", which is a built-in type
          of the language, that means you can use it in the global
          scope(wherever in your program).
          But "struct point" is a type you defined yourself, and you have
          defined it in function main(), so you have to use it just within the
          local-scope of main. In your code, you defeined a function return type
          struct point out of the local-scope of main, it breaks the rule
          mentioned above.:-)

          Comment

          • mdh

            #6
            Re: K&amp;R p 130

            On Aug 17, 1:25 am, "Malcolm McLean" <regniz...@btin ternet.comwrote :
            "mdh" <m...@comcast.n etwrote in message
            >
            >
            The struct is not local to main. It is used in another function.
            Similarly if you called foo() from anywhere except main(), you'd have to
            prototype it again.
            This is why we normally place structures and prototypes at the top of the
            file, usually wrapped up into a header.
            >

            Well, this is really disheartening, as I thought I had it figured
            out.


            If we have:


            int main ( void){

            int foo( void);

            int i = foo;

            printf("...etc ");

            return 0;
            }


            int foo (void){
            do stuff;
            return stuff;
            }


            This seems to compile and work. I also thought declaring foo() before
            main allowed it to be "seen" throughout the translation unit, but
            within main, only to be seen, but still to be legally used if I called
            it as above. How then, did this differ from declaring the struct
            "point" and function returning "point" within main and calling it from
            within main. I hope this makes sense.
            Thanks in advance for clarifying this.






            Comment

            • pete

              #7
              Re: K&amp;R p 130

              mdh wrote:
              int foo( void);
              >
              int i = foo;
              This seems to compile and work.
              Initializing an int object
              with a function name
              does not seem to compile and work.

              --
              pete

              Comment

              • mdh

                #8
                Re: K&amp;R p 130

                On Aug 17, 2:39 am, pete <pfil...@mindsp ring.comwrote:
                >
                >
                Initializing an int object
                with a function name
                does not seem to compile and work.

                OK...here is my tested example.

                #include <stdio.h>

                int main (int argc, const char * argv[]) {

                double foo( double);
                double d = foo(8);
                printf( "%f", d); /* 14.000000 */
                return 0;
                }


                double foo ( double d){
                return 6.0 + d;
                }

                Comment

                • Ben Bacarisse

                  #9
                  Re: K&amp;R p 130

                  mdh <mdeh@comcast.n etwrites:
                  On Aug 17, 2:39 am, pete <pfil...@mindsp ring.comwrote:
                  >>
                  >Initializing an int object
                  >with a function name
                  >does not seem to compile and work.
                  >
                  OK...here is my tested example.
                  >
                  #include <stdio.h>
                  >
                  int main (int argc, const char * argv[]) {
                  >
                  double foo( double);
                  double d = foo(8);
                  printf( "%f", d); /* 14.000000 */
                  return 0;
                  }
                  >
                  double foo ( double d){
                  return 6.0 + d;
                  }
                  Yes, a correct use of a function prototype with block scope. In your
                  struct example, the struct also had block scope and so was not
                  available at file scope when the function was defined. Nothing in the
                  definition of foo requires anything from the block of main so the
                  definition matches the prototype as required.

                  --
                  Ben.

                  Comment

                  • mdh

                    #10
                    Re: K&amp;R p 130

                    On Aug 17, 6:50 am, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
                    mdh <m...@comcast.n etwrites:
                    >
                    #include <stdio.h>
                    >
                    int main (int argc, const char * argv[]) {
                    >
                       double foo( double);
                       double d = foo(8);
                       
                    >snip
                    }
                    >
                    double foo ( double d){
                       return 6.0 + d;
                    }
                    >
                    ......... In your struct example, the struct also had block scope and sowas not
                    available at file scope when the function was defined.  ...... Nothing in the
                    definition of foo requires anything from the block of main........
                    >
                    Firstly, thank you for answering.
                    So Ben, what am I missing, or is this just C fatigue? I **thought**
                    (obviously incorrectly :-)), ( but without understanding why) that I
                    had, within the block of main,

                    declared the struct point, then declared a function called makepoint,
                    then outside of main, defined the function makepoint. I know what you
                    are saying about block scope, but on the face of it, why is this so
                    different from my example of foo that you say is correct. And...I
                    apologize in advance for belaboring this point.

                    Comment

                    • mdh

                      #11
                      Re: K&amp;R p 130

                      On Aug 17, 7:47 am, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
                      .  Let me write it out
                      compressed for convenience:
                      >
                      int main(void)
                      {
                          struct point { int x, y; };       /* The struct tag point has a */
                          struct point makepoint(int, int); /* meaning all the way down */
                          struct point p = makepoint(1, 2); /* to here... */
                      >
                      }
                      >
                      struct point makepoint(int a, int b) /* ... but not here where it */
                      {                                    /* is also needed. */
                        /* stuff */
                      >
                      }
                      >
                      Outside main, "struct point" has no meaning, so the definition is
                      rejected.

                      OK...I think I am getting it.
                      Is this then correct.

                      A struct is a type ( just like int is a type) but one which I ( the
                      programmer...if I can call myself that :-) ) are able to declare. So,
                      essentially, up to now, when I have declared *anything* within main,
                      it has always been of a type that was ?"inherent" to C, unlike my own
                      type "point" which I need when defining "makepoint" . So,
                      theoretically , "re-declaring" it just before the definition would
                      work, except it would be "clunky" and in any case, that is in essence
                      what one is doing by moving the declarations outside of main.


                      Comment

                      • mdh

                        #12
                        Re: K&amp;R p 130

                        On Aug 17, 7:47 am, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
                        >
                        Your function foo does not rely on anything with a limited scope.  Its
                        return type and parameter type are all keywords that have the same
                        meaning everywhere.  If any of these types involved identifiers with
                        function scope, it too would have gone wrong.
                        >
                        One last little point. The identifier "foo" as in the following.


                        int main(void){

                        sometype foo ( some argument );

                        use foo;


                        }


                        sometype foo ( some arguments){};
                        }

                        When I call "foo" in main, that identifier does "know" where to find
                        the definition of foo. The identifier "foo" though has block scope, if
                        I understand this correctly.
                        So, how then does the call to foo get handled correctly?

                        Thank you.



                        Comment

                        • Ben Bacarisse

                          #13
                          Re: K&amp;R p 130

                          mdh <mdeh@comcast.n etwrites:
                          On Aug 17, 7:47 am, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
                          >
                          >>
                          >Your function foo does not rely on anything with a limited scope.  Its
                          >return type and parameter type are all keywords that have the same
                          >meaning everywhere.  If any of these types involved identifiers with
                          >function scope, it too would have gone wrong.
                          >>
                          >
                          >
                          One last little point. The identifier "foo" as in the following.
                          >
                          >
                          int main(void){
                          >
                          sometype foo ( some argument );
                          >
                          use foo;
                          >
                          >
                          }
                          >
                          >
                          sometype foo ( some arguments){};
                          }
                          >
                          When I call "foo" in main, that identifier does "know" where to find
                          the definition of foo. The identifier "foo" though has block scope, if
                          I understand this correctly.
                          No, there are two identifiers with the same letters and thus two
                          scopes. They are "linked" by the fact the declaration of foo in
                          main is, by default, a declaration of a function with extern linkage.
                          So, how then does the call to foo get handled correctly?
                          I don't know how to answer questions like this, because I don't see
                          the problem! Maybe I have answered it with the above clarification.

                          --
                          Ben.

                          Comment

                          • mdh

                            #14
                            Re: K&amp;R p 130

                            On Aug 17, 8:28 am, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
                            The key part is "declared in separate translation units".  Two
                            structs, declared in the same translation unit, even in separate
                            scopes, can't ever be compatible -- no matter how similar they look.
                            >
                            >
                            OK..., this is unique only to structs, unions and enums. And if so,
                            is this due to the complicated nature of those objects, and perhaps
                            the way C stores them internally? Or...that's just the way it
                            is? :-)

                            If so, thanks again for clarifying this issue for me.

                            Comment

                            • mdh

                              #15
                              Re: K&amp;R p 130

                              On Aug 17, 8:47 am, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
                              >
                              No, there are two identifiers with the same letters and thus two
                              scopes.  They are "linked" by the fact the declaration of foo in
                              main is, by default, a declaration of a function with extern linkage.
                              >
                              So, how then does the call to foo get handled correctly?
                              >
                              Thanks Ben...

                              Comment

                              Working...