jkelly@world.std.com (john c kelly) (03/23/91)
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 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 : struct defs { ... some stuff ... some more stuff }; /* <--- should be a declarator here. */ 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 further compile errors becasue the compiler gives the definition of 'struct defs' tag in function s22 file scope, 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. 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. ANY help or suggstions would be greatly appreciated. If possible e-mail directly to me I'll summarize if enough interest. John C. Kelly MaBell: 717-986-5038 Prime System Integration (prefered)--> Prime: j.kelly@md-b.prime.com Prime Computer Inc. Client: ampt0659@s2901b.amp.com DISCLAIMER: I speak for me. Only. Home: jkelly@world.std.com "You can demonstrate a program for an executive - but you can't make him computer literate." -- John C. Kelly MaBell: 717-986-5038 Prime System Integration Prime: j.kelly@md-b.prime.com Prime Computer Inc. Client: ampt0659@s2901b.amp.com
henry@zoo.toronto.edu (Henry Spencer) (03/24/91)
You do not specify where the troublesome declarations were, and that is crucial. Context indicates they were within a function, but it matters a lot whether they were in the parameter list or inside the {}. The rule quoted from 3.7.1 really does constrain parameter-list declarations to contain at least one declarator. No such constraint applies to declarations within the function body. Many older compilers were looser about what they allowed in parameter lists. Argument by example is always unreliable, and is especially so for C, because many superfically-different C compilers have common ancestry. > ... 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. Now *this* sounds seriously bogus. Struct tags obey the same scope rules as other declared identifiers. -- "[Some people] positively *wish* to | Henry Spencer @ U of Toronto Zoology believe ill of the modern world."-R.Peto| henry@zoo.toronto.edu utzoo!henry
bhoughto@nevin.intel.com (Blair P. Houghton) (03/24/91)
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@world.std.com> jkelly@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."