Velocity Reviews > A clarification please

mdh
Guest
Posts: n/a

 08-18-2008
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.

jameskuyper@verizon.net
Guest
Posts: n/a

 08-18-2008
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.

Barry Schwarz
Guest
Posts: n/a

 08-18-2008
On Mon, 18 Aug 2008 15:23:06 -0700 (PDT), mdh <(E-Mail Removed)>
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?

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

mdh
Guest
Posts: n/a

 08-19-2008
On Aug 18, 4:40*pm, (E-Mail Removed) 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.

Thank you for that explanation.

mdh
Guest
Posts: n/a

 08-19-2008
On Aug 18, 4:48*pm, Barry Schwarz <(E-Mail Removed)> wrote:
> On Mon, 18 Aug 2008 15:23:06 -0700 (PDT), mdh <(E-Mail Removed)>
> 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?
>

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
Guest
Posts: n/a

 08-19-2008
On Aug 18, 5:45*pm, Richard Heathfield <(E-Mail Removed)> 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
Guest
Posts: n/a

 08-19-2008
On Aug 18, 5:45*pm, Richard Heathfield <(E-Mail Removed)> 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
Guest
Posts: n/a

 08-19-2008
On Aug 18, 10:36*pm, Richard Heathfield <(E-Mail Removed)> 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.