A clarification please

Discussion in 'C Programming' started by mdh, Aug 18, 2008.

  1. mdh

    mdh Guest

    FAQ 1.7 shows that, amongst other things,

    int i = 0;

    is a definition.

    Page 128 of K&R say:

    "A struct declaration defines a type. The right brace that terminates
    the list of members may be followed by a list of variables, just as
    for any basic type. That is,

    struct {.....} x, y, z:

    is syntactically analogous to

    int x, y, z;

    in the sense that each statement declares x, y, and z to be variables
    of the named type **and causes space to be set aside for them**. {My
    emphasis}

    My understanding was that a definition causes space to be set aside,
    ( eg int i = 0) but not a declaration ( eg int i) and the x, y, and z
    in the above example. How can these two ideas be reconciled?

    Thanks as usual.
     
    mdh, Aug 18, 2008
    #1
    1. Advertising

  2. mdh

    Guest

    mdh wrote:
    > FAQ 1.7 shows that, amongst other things,
    >
    > int i = 0;
    >
    > is a definition.
    >
    > Page 128 of K&R say:
    >
    > "A struct declaration defines a type. The right brace that terminates
    > the list of members may be followed by a list of variables, just as
    > for any basic type. That is,
    >
    > struct {.....} x, y, z:
    >
    > is syntactically analogous to
    >
    > int x, y, z;
    >
    > in the sense that each statement declares x, y, and z to be variables
    > of the named type **and causes space to be set aside for them**. {My
    > emphasis}
    >
    > My understanding was that a definition causes space to be set aside,
    > ( eg int i = 0) but not a declaration ( eg int i) and the x, y, and z
    > in the above example. How can these two ideas be reconciled?


    By noting that your concept of what a definition is isn't quite right.

    A declaration that explicitly initializes the value of a variable is
    always a definition. The same is true of a file scope declaration
    using the keyword 'static', or any other declaration that does not use
    the keyword 'extern'. That last case covers 'int i;' when it occurs at
    block scope.

    However, all other variable declarations are considered "tentative",
    including "int i;" if it occurs at file scope, and that's where it
    gets tricky. If a tentative definition is followed by a later
    declaration of the same variable name in the same scope that includes
    an initializer or uses the keyword 'static', the tentative definition
    becomes a real definition. If, by the end of the translation unit,
    there are no non-tentative definitions of a variable, then the
    tentative definition becomes a real one, unless it was declared
    'extern', in which case it becomes a declaration of a variable who's
    actual definition lies elsewhere.
     
    , Aug 19, 2008
    #2
    1. Advertising

  3. On Mon, 18 Aug 2008 15:23:06 -0700 (PDT), mdh <>
    wrote:

    >FAQ 1.7 shows that, amongst other things,
    >
    >int i = 0;
    >
    >is a definition.
    >
    >Page 128 of K&R say:
    >
    >"A struct declaration defines a type. The right brace that terminates
    >the list of members may be followed by a list of variables, just as
    >for any basic type. That is,
    >
    >struct {.....} x, y, z:
    >
    >is syntactically analogous to
    >
    >int x, y, z;
    >
    >in the sense that each statement declares x, y, and z to be variables
    >of the named type **and causes space to be set aside for them**. {My
    >emphasis}
    >
    >My understanding was that a definition causes space to be set aside,
    >( eg int i = 0) but not a declaration ( eg int i) and the x, y, and z
    >in the above example. How can these two ideas be reconciled?


    By correcting your understanding.

    int i; is a definition. It causes space to be set aside (in some
    implementation specific sense of the phrase) for object i. If it
    didn't, code such as i = j+k; would have no place to store the result.

    extern int i; is a declaration. It promises that i is in fact defined
    somewhere else and the linker will be able to resolve its location.

    struct t {...}; is a declaration. It doesn't define an object. It
    does "define" a new type. (I prefer to say it declares the type but
    it's hard to argue with K&R.) In any event, defining a type is
    different than defining an object or function. struct t {...} x; is a
    definition. It defines the object x and reserves space for it.

    All of which proves that the word "define" and words derived from it
    mean different things when used to describe the creation of objects or
    used to describe other aspects of the language.

    This is not that unusual. The word "token" means different things
    when talking about the preprocessor, language syntax, or the use of
    the standard function strtok. Context is important when trying to
    decide what things mean.

    --
    Remove del for email
     
    Barry Schwarz, Aug 19, 2008
    #3
  4. mdh

    mdh Guest

    On Aug 18, 4:40 pm, wrote:
    > mdh wrote:
    > > FAQ 1.7 shows that, amongst other things,

    >
    > > int i = 0;

    >
    > > is a definition.

    >
    > > Page 128 of K&R say:

    >
    > > "A struct declaration defines a type. The right brace that terminates
    > > the list of members may be followed by a list of variables, just as
    > > for any basic type. That is,

    >
    > > struct {.....}  x, y, z:

    >
    > > is syntactically analogous to

    >
    > > int x, y, z;

    >
    > > in the sense that each statement declares x, y, and z to be variables
    > > of the named type **and causes space to be set aside for them**.  {My
    > > emphasis}

    >
    > > My understanding was that a definition causes space to be set aside,
    > > ( eg int i = 0)  but not a declaration ( eg int i) and the x, y, and z
    > > in the above example. How can these two ideas be reconciled?

    >
    > By noting that your concept of what a definition is isn't quite right.
    >
    > A declaration that explicitly initializes the value of a variable is
    > always a definition. The same is true of a file scope declaration
    > using the keyword 'static', or any other declaration that does not use
    > the keyword 'extern'. That last case covers 'int i;' when it occurs at
    > block scope.
    >
    > However, all other variable declarations are considered "tentative",
    > including "int i;" if it occurs at file scope, and that's where it
    > gets tricky. If a tentative definition is  followed by a later
    > declaration of the same variable name in the same scope that includes
    > an initializer or uses the keyword 'static', the tentative definition
    > becomes a real definition. If, by the end of the translation unit,
    > there are no non-tentative definitions of a variable, then the
    > tentative definition becomes a real one, unless it was declared
    > 'extern', in which case it becomes a declaration of a variable who's
    > actual definition lies elsewhere.


    My head is spinning!! :)

    Thank you for that explanation.
     
    mdh, Aug 19, 2008
    #4
  5. mdh

    mdh Guest

    On Aug 18, 4:48 pm, Barry Schwarz <> wrote:
    > On Mon, 18 Aug 2008 15:23:06 -0700 (PDT), mdh <>
    > wrote:
    >
    >
    >
    > >FAQ 1.7 shows that, amongst other things,

    >
    > >int i = 0;

    >
    > >is a definition.

    >
    >
    > >struct {.....}  x, y, z:

    >


    t declares x, y, and z to be variables
    > >of the named type **and causes space to be set aside for them**.  {My
    > >emphasis}

    >
    > How can these two ideas be reconciled?
    >
    > By correcting your understanding.



    That, sadly, has been happening a lot lately!! :)

    >
    > int i; is a definition.  It causes space to be set aside (in some
    > implementation specific sense of the phrase) for object i.  If it
    > didn't, code such as i = j+k; would have no place to store the result.
    >
    > extern int i; is a declaration.  It promises that i is in fact defined
    > somewhere else and the linker will be able to resolve its location.
    >
    > struct t {...}; is a declaration.  It doesn't define an object.  It
    > does "define" a new type.  (I prefer to say it declares the type but
    > it's hard to argue with K&R.)  In any event, defining a type is
    > different than defining an object or function.  struct t {...} x; is a
    > definition.  It defines the object x and reserves space for it.  
    >
    > All of which proves that the word "define" and words derived from it
    > mean different things when used to describe the creation of objects or
    > used to describe other aspects of the language.
    >
    > This is not that unusual.  The word "token" means different things
    > when talking about the preprocessor, language syntax, or the use of
    > the standard function strtok.  Context is important when trying to
    > decide what things mean.
    >



    thank you Barry. That does clarify it.
     
    mdh, Aug 19, 2008
    #5
  6. mdh

    mdh Guest

    On Aug 18, 5:45 pm, Richard Heathfield <> wrote:

    >
    > I think your take was based on a possible misunderstanding of what
    > constitutes a definition. It is not syntactically necessary for there to
    > be an initialiser in order for a declaration to become a definition.
    >



    Thanks Richard.
     
    mdh, Aug 19, 2008
    #6
  7. mdh

    mdh Guest

    On Aug 18, 5:45 pm, Richard Heathfield <> wrote:
    > mdh said:
    >
    > > FAQ 1.7 shows that, amongst other things,

    >
    > All definitions are also declarations. Not all declarations are
    > definitions, however.
    >
    > struct foo x, y, z; is a definition (and of course a declaration, but the
    > important point here is that it is a definition). It defines (reserves
    > storage for) x, y, and z, which are all objects of type struct foo.
    >
    >




    May I pursue this for just a moment. In another thread, I got a very
    extensive ( and appreciated) answer to the question of "re-declaring
    a struct" from BB.


    >>>>>

    Re-declaring it won't work. The standard says this:
    "Moreover, two structure, union, or enumerated types declared in
    separate translation units are compatible if their tags and
    members
    satisfy the following requirements: ..."
    [you can stop reading here if you like]
    "... If one is declared with a tag, the other shall be declared
    with the same tag. If both are complete types, then the following
    additional requirements apply: there shall be a one-to-one
    correspondence between their members such that each pair of
    corresponding members are declared with compatible types, and such
    that if one member of a corresponding pair is declared with a
    name,
    the other member is declared with the same name. For two
    structures, corresponding members shall be declared in the same
    order. For two structures or unions, corresponding bit-fields
    shall
    have the same widths."
    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.
    <<<<<



    So, I made up this little bit of code.

    #include <stdio.h>

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


    int foo (int); /* first declaration of foo */

    int x = foo (7);
    int foo (int); /* 2nd declaration of foo */
    /* no error */


    struct name { /* first declaration of struct */
    int x;
    };

    struct name { /*error : Redefinition of struct name */
    int x;
    };

    struct name p = {
    20
    };

    return 0;
    }


    int foo (int x){
    return 9;
    }


    From Ben's note, I expected to get a re-declaration error, (for the
    struct) not a redefinition error. Moreover, if the declaration is
    placed at block level, and a second declaration is placed at file
    level, there is not error generated. ( From my understanding of
    declaration of functions, I did not expect an error for foo, and got
    none. ) Any insight is appreciated. Thanks in advance.
     
    mdh, Aug 19, 2008
    #7
  8. mdh

    mdh Guest

    On Aug 18, 10:36 pm, Richard Heathfield <> wrote:
    > mdh said:
    >
    >
    > > struct name {  /* first declaration of struct */
    > > int x;
    > > };

    >
    > > struct name {  /*error : Redefinition of struct name */
    > > int x;
    > > };

    >
    > I think the reason you're confused may be that you are conflating two
    > different meanings of the word "definition". The meaning we've been
    > discussing recently is the definition of an identifier to describe an
    > object. But:
    >
    > struct name { int x; };
    >



    > doesn't define an object - it defines a *type*. Within a given scope, you
    > can only define a type once.
    >


    Aha...that's what I have been missing. Thank you Richard.
     
    mdh, Aug 19, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KK
    Replies:
    2
    Views:
    646
    Big Brian
    Oct 14, 2003
  2. Totti
    Replies:
    2
    Views:
    277
  3. naren
    Replies:
    2
    Views:
    527
    debayan_p
    Aug 24, 2009
  4. Mohsen Akhavan

    Foxruby codes clarification please!

    Mohsen Akhavan, Jan 16, 2006, in forum: Ruby
    Replies:
    0
    Views:
    99
    Mohsen Akhavan
    Jan 16, 2006
  5. Tim Pease
    Replies:
    7
    Views:
    121
    Chris Shea
    Jul 3, 2007
Loading...

Share This Page