[comp.std.c] Misdeclaring "main"

mcdaniel@uicsrd.csrd.uiuc.edu (Tim McDaniel) (07/29/89)

This is cross-posted to comp.lang.c (original article's newsgroup) and
comp.std.c (I have standards questions).  Followups have been
redirected to comp.std.c.

In article <13104@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve
Summit) writes:
>The production
>
>	struct { struct-decl-list } id (arg-list) decl-list compound-statement
>
>yields a function that cannot be (correctly) called, since no
>other object can be declared with a type-equivalent structure.

I'm not so sure.  Separate compilation is allowed in C, but struct
tags (and their definitions) are not global in scope; for external
linkage, only the types and order of the struct's members matter.
I would think the following declarations are strictly conforming:

in foo.c:
        extern struct { int f1; float f2; } func(); ...

in bar.c:
        struct { int a6; float whacky; } func() ...

However, K&R 2, 1st edition, p. 213 says

     A structure or union specifier with a list but no tag creates a
     unique type; it can referred to directly only in the declaration
     of which it is a part.

>The production
>
>	struct tag { struct-decl-list } id (arg-list) ...
>
>yields a function that can only be called by routines appearing
>later in the same file.

This statement is even more problematical.  How does it differ from
	struct tag { struct-decl-list };
        struct tag id (arg-list) ...
?  If there is no difference, the "struct tag" declaration could just
as easily be in an include file, and another file could include it and
declare
        extern struct tag id ();
Surely *this* behavior is blessed by the standard.

--
"Let me control a planet's oxygen supply, and I don't care who makes
the laws." - GREAT CTHUHLU'S STARRY WISDOM BAND (via Roger Leroux)
 __
   \         Tim, the Bizarre and Oddly-Dressed Enchanter
    \               mcdaniel@uicsrd.csrd.uiuc.edu
    /\       mcdaniel%uicsrd@{uxc.cso.uiuc.edu,uiuc.csnet}
  _/  \_     {uunet,convex,pur-ee}!uiucuxc!uicsrd!mcdaniel

scs@adam.pika.mit.edu (Steve Summit) (08/01/89)

In article <1612@garcon.cso.uiuc.edu> mcdaniel@uicsrd.csrd.uiuc.edu (Tim McDaniel) writes:
>This is cross-posted to comp.lang.c (original article's newsgroup) and
>comp.std.c (I have standards questions).  Followups have been
>redirected to comp.std.c.

Pooh.  Now I have to be more careful than I can be, without a
copy of the draft at hand...

>In article <13104@bloom-beacon.MIT.EDU> scs@adam.pika.mit.edu (Steve
>Summit) writes:
>>The production
>>	struct { struct-decl-list } id (arg-list) decl-list compound-statement
>>yields a function that cannot be (correctly) called, since no
>>other object can be declared with a type-equivalent structure.
>
>I'm not so sure.  Separate compilation is allowed in C, but struct
>tags (and their definitions) are not global in scope; for external
>linkage, only the types and order of the struct's members matter.

It has been suggested that permission to base struct equivalence
across files on types and order, rather than the stricter means
required within one file, is an exception, reflecting the
realities of conventional implementations of separate compilation.
The way I think about it is that this is perfectly legal:

	s.h:	struct s {int i;};

	a.c:	#include "s.h"		b.c:	#include "s.h"
		struct s s;			extern struct s s;

while this is suspect:

	a.c:	struct s {int i;};	b.c:	struct s {int i;};
		struct s s;			extern struct s s;

Obviously, a conventional compiler cannot tell these two cases
apart, which is why the exception allows the two struct s's in
the second example to be considered equivalent.  I would not mind
it if a smart compiler (or, more preferably, lint) complained
about the second form.

I have no idea what the chapter and verse of the pANS says on
this issue (that's why I'd have kept this in comp.lang.c...).
I'm describing a conceptual ideal, based on the obvious stylistic
requirement of describing the structure in exactly one place.  If
the pANS is less stringent (if its permission to base inter-file
struct equivalence on type and order is not an exception, as I
have suggested, but rather explicit and genuine) then I have no
complaint with it, and you don't need to correct me here.  (The
standard tries to, and should, be pragmatic.)  I hope we agree
why the first sample code above is vastly preferable to the
second.

>>The production
>>	struct tag { struct-decl-list } id (arg-list) ...
>>yields a function that can only be called by routines appearing
>>later in the same file.
>
>This statement is even more problematical.  How does it differ from
>	struct tag { struct-decl-list };
>        struct tag id (arg-list) ...
>?  If there is no difference, the "struct tag" declaration could just
>as easily be in an include file, and another file could include it...

Of course.  The difference between

	struct tag { struct-decl-list } id (arg-list) ...
and
	struct tag { struct-decl-list };
	...
	struct tag id (arg-list) ...

is precisely, and only, that the second form affords more
possibilities for equivalent declarations of type "struct tag,"
especially if the tag is defined in a header file.  That is
exactly what I was trying to show.

I listed three productions:

 1.	struct { struct-decl-list } id (arg-list) decl-list compound-statement
 2.	struct tag { struct-decl-list } id (arg-list) ...
 3.	struct tag id (arg-list) ...

and suggested that the first one was, in practice, useless; the
second one (theoretically) barely useful; and the third one the
only one that would ever appear in real and/or well-written
programs.

Between the lines is a question, which I'll make explicit: if, in
an attempt to catch the common mistake of misdeclaring main (or
another function) by leaving out a semicolon after a preceding
structure declaration, a compiler were to issue warnings for
productions 1. and 2. above, would these warnings be elicited
inappropriately for anyone's real programs?  (No contrived
examples or obfuscated C contest entries, of course.)

                                            Steve Summit
                                            scs@adam.pika.mit.edu