ANSI vs K&R 3.7.1 structures Help!

Blair P. Houghton bhoughto at nevin.intel.com
Sun Mar 24 13:55:09 AEST 1991


Henry's right, it's not clear where you made this declaration.

Your supplier's citation of X3.159-1989, however,
applies to only two situation, which are:

    type1 s22( struct defs { ... }; struct defs *pdo ) /* <--parameter list */
    {                         /*  ^missing identifier */
            ...
    }

and:

    type1 s22( pdo )            /* <-- identifier list */
    struct defs { ... }; struct defs *pdo;
    {
	    ...
    }

Both of these are declaring two parameters, but listing only one.

Similarly

    struct defs {
       ...
    };

    type1 func( bar )            /* <-- identifier list */
    struct defs;
    {
	    ...
    }

This is broken not because the listed parameter is not declared,
but because the declaration specifier `struct defs' does not
declare one of the listed parameters.  In the absence of a declaration,
the listed parameters' types default to `int'.  Here, though,
the extraneous declaration ought to cause compilation to end.

In article <1991Mar22.183721.11779 at world.std.com> jkelly at world.std.com (john c kelly) writes:
>
>         Sorry to bother everyone but  I  am  about to port a fair size
>    application from one machine to another.  I had not done much  work
>    on  the  target  machine  so  I  decided to checkout the compiler's
>    capabilities.  I took a copy  of  the  C torture tests and tried to

Torture tests?  This one seems to have broken
down when shown to a suite at the Marriott... :-)

>    compile the code on the new machine.  I could not  do  the  testing
>    myself, the  system administrator  had to,  so I  placed all of the
>    code  into  one single file and he ran the compiler, which promptly
>    died.  The sysadmin put in  a  service  call and sent a copy of the
>    code to the engineers  and they replied:
>
>              This note is to explain why we do not think that the
>         test case code is a valid ANSI C program.  Please note we
>         only  support the K&R standard where it agrees with ANSI.
>
>              In ANSI  3.7.1,  5th  paragraph  of the 'Contraints'
>         section, it  states:   'If  the  declarator  includes  an
>         identifier list, each declaration in the declaration list
>         shall have at least one declarator, and those declarators
>         shall declare only identifiers from the identifier list.'
>
>              The  key  point  is  that  each function must have a
>         declarator.
>
>
>         In function s22(pd0) you declared a structure :

"In function" does not invoke para 5 of 3.7.1.

"In the parameter declarations for function", would.

>
>              struct defs {
>                            ... some stuff
>                            ... some more stuff
>              };     /* <--- should be a declarator here. */

There most explicitly may be no declarator there.  The
standard is full of examples of this sort of declaration.

>              struct defs *pd0;
>
>
>              The problem with your code is that the 'struct defs'
>         statement does  not  have  a  declarator.   The  compiler
>         dosen't  like  the  semi-colon because it is expecting an
>         identifier for the  declarator.
>
>              The following is what  the ANSI version of the above
>         code looks like:
>
>
>              struct defs {
>                            ... some stuff
>                            ... some more stuff
>              } *pd0;  /* <--- now the declaration has a declarator. */
>
>
>              We converted the test case to ANSI format,  and  got

Bogus "ANSI format".  Not even KnR would allow you to put an
declaratorless structure definition in the parameter declarators;
but I don't think you did, anyway.

>         further  compile  errors  becasue  the compiler gives the
>         definition of  'struct  defs'  tag  in  function s22 file
>         scope,

This is illegal.  Even if the tag's declaration appears in the
parameter list or identifier list declarators, it has
scope within the function only, just as does the parameter
identifier.

>         and so  each  subsequent  declaration  of  'struct
>         defs' receives an error message that stuct tags cannot be
>         redefined.   The  way  to  resolve that is to only do one
>         defintion of the 'struct  defs' tag.

The way to resolve it is to fix the compiler.

>         HELP!   I am highly suspicious of their response.  I have used
>    this stye of code before.  In  fact  the code compiles fine using 5
>    other compilers!   I don't  have the  ANSI spec  to quote from so I
>    appeal to the C-NET-GODS to tell me if they are blowing smoke or  I
>    am  just  stupid.  One thing that really wories me is that they say
>    the 'stuct defs' tag  has  been  given file scope.  It was declared
>    INSIDE the function!  I thought that this made it local not global.

You're exactly correct.  It would have block scope.  Giving
it file scope when it does not appear outside of a function
definition or a block is broken, broken, broken.

Is this what you did?

        type1 s22 ( ... )
        ...
        {
            struct defs {
                ...
            };
            ...
            struct defs *pdo;
            ...
        }

If it is, then you did right.  3.7.1 has absolutely nothing
to do with this, since 3.7.1 applies only to function
definitions, and has no bearing on structure definitions.

Tell these "engineers" to read ANSI X3.159-1989, sec.
3.1.2.1, p. 21, ll. 27-42, taking note that scope is
defined by where the identifier "appears", and in the case
of tags (a tag is an identifier; see sec. 3.5.2.3) the
scope "begins just after the appearance of the tag in a
type specifier that declares the tag," which means only
that it doesn't have scope before the tag appears.  Most
importantly, that latter phrase does not change the point
at which the scope ends, which in your case is the closing
`}' of that function's body's block.

Nothing you show indicates that any part of your structure
should get file scope.

Show them also sec. 3.5, p. 58, l. 4.  It clearly
shows that the init-declarator-list in a declaration
is OPTIONAL.  l. 16 states that the minimum a declaration
must do is declare one of "a declarator, a tag, or the
members of an enumeration."  You satisfied that with `defs'.

You can leave out the variable declarators.

>         ANY  help  or  suggstions  would  be  greatly appreciated.  If
>    possible e-mail directly to  me  I'll summarize if enough interest.

What? and miss a chance to flame a truly broken compiler implementation?

The only way you could have gone wrong is if you did:

    /* no prior declaration of `defs' in scope */

    type1 s22 ( ... )
    ...
    {                           /* begin block */
        struct defs {           /* block-scope `defs' */
            ...
        };                      /* legally absent init-declarator-list */
        ...
    }                           /* end block */
    ...
    struct defs *pdo;           /* `defs' ended scope at `}' */

or:

    /* no prior declaration of `defs' in scope */

    type1 s22(pdo)
    struct defs pdo;            /* `defs' not yet in scope */
    {
        struct defs {           /* scope of `defs' begins here */
            ...
        };
        ...
    }

which mean that the tag `defs' is undefined when you declare pdo.

                                --Blair
                                  "Warning: illegal use of ellipsis."



More information about the Comp.std.c mailing list