Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!lll-tis!ames!ptsfa!ihnp4!homxb!mhuxt!m10ux!mnc From: mnc@m10ux.UUCP (Michael Condict) Newsgroups: comp.lang.c Subject: Re: Clarifications on ANSI C nits Message-ID: <458@m10ux.UUCP> Date: 28 Dec 87 04:04:45 GMT References: <3725@hoptoad.uucp> Organization: AT&T Bell Labs, Murray Hill Lines: 95 Summary: silly syntactic inconsistencies In article <3725@hoptoad.uucp>, gnu@hoptoad.uucp (John Gilmore) writes: > While testing the GNU C compiler using the MetaWare C Validation Suite, > I found a bunch of things that are not clearly marked in the Oct 86 copy > of the C draft standard. I'm interested in clarification from the group > and/or from the standards committee on these: > > . . . > > * It appears from the text in section 3.5.3.3 that variable-argument-list > functions can ONLY be defined in the > > foo(int c, float bar, ...) > > syntax, and not in the > > foo(c, bar, ...) > int c; > float bar; > > syntax. GCC implements it this way. However, this makes it impossible > to support since no existing code uses the new declaration > method. It also seems to be a silly inconsistency. Another silly inconsistency (although it is probably too late to fix in the current standard) is the use of comma instead of semicolon in the new declaration syntax. There already were at least three places in the existing language where one could write a sequence of declarations of names, e.g. in struct declarations between { and }, and in the old-style declaration of the formal args of a function. In all these places, semicolons are used to terminate each declaration, not comma. This is crucial, because comma is also allowed in these constructs and serves to concisely declare a list of identifiers of the same type: int a,b,c; The ANSI committee's adopted syntax introduces two defects in the language: (1) It confuses users by being inconsistent with these other, highly analogous syntactic constructs, and for the same reason makes parsers unnecessarily complex. (2) It eliminates the possibility of allowing the concise declaration syntax shown above in the new declaration syntax. My guess is that the committee's choice of syntax was based on reasoning something like: "currently, commas are required between formal arguments in the header of the function (i.e., between '(' and ')'), so we must preserve that to avoid confusing users." This argument however is less than persuasive if we note that the addition of the new declaration syntax so radically alters what is allowed inside the () that some users are bound to be confused anyway. And besides, it is easy to describe my advocated version of the new declaration syntax in words that make it out to be a natural extension of the old syntax: (1) In K&R C, the construct "f(a,b,c) ... {" is an abbreviation for "f(int a,b,c;) ... {". (Note that these same two abbreviations are allowed elsewhere in the language.) The meaning is that a, b and c are all declared to be ints, as is the case elsewhere in the language, except that their declaration(s) can be overridden by a redeclaration in the ... stuff between ')' and '{'. This is consistent with how things work now. (2) In ANSI C, the type word "int" may not be omitted, just as it may no longer be omitted elsewhere in the language. The trailing ";" is still optional. (3) Furthermore, in ANSI C, we extend the syntax and semantics to allow an arbitrary sequence of declarations inside the (), with the semicolon optional for the last one. E.g.: f(int a,b; struct {float i,r;}) { (We should probably also allow bit field declarations, since our syntax and semantics is essentially equivalent to the case where every function takes one argument, but that argument is a struct type. No new implementation difficulties arise, since it is already legal to declare a function that takes as argument a struct with bitfields.) (4) Now, since any types of arguments can be declared without putting stuff between ')' and '{', we don't allow you to redeclare args there, with one exception: for backward compatibility, we allow the old style declaration, at least until the next version of the standard, but it is a depecrated feature. That is, you can still abbreviate "int a,b,c" to "a,b,c", and if your entire declaration sequence within () consists of such an abbreviation, you can redeclare the types of some or all of the args, using declarations occurring between ')' and '{'. Described this way, it is clear why (my version of) the new syntax is to be preferred to K&R syntax: it doesn't make sense to be declaring the args as ints inside of the () then redeclaring them afterwards. Am I the only one bothered by this? I've noticed no other discussion of it. -- Michael Condict {ihnp4|vax135|cuae2}!m10ux!mnc AT&T Bell Labs (201)582-5911 MH 3B-416 Murray Hill, NJ