Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!1.eu.feeder.erje.net!newsfeed.fsmpi.rwth-aachen.de!newsfeed.straub-nv.de!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Making C more beautiful by not using macros with arguments Date: Sun, 31 May 2015 13:04:35 -0700 Organization: None to speak of Lines: 65 Message-ID: <87r3pwikdo.fsf@kst-u.example.com> References: <032b4cc1-a813-4caa-a810-569e1ea3b0ab@googlegroups.com> <87h9qvkzpb.fsf@bsb.me.uk> <0f75266c-9fff-439e-98a3-4140f21e04d5@googlegroups.com> <87fv6dkd7f.fsf@bsb.me.uk> <87a8wlk5o3.fsf@bsb.me.uk> <87zj4lhxsc.fsf@bsb.me.uk> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="9be37d943435275679235b07c7947eef"; logging-data="31299"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19HOcqLdDXrPxTM+G2eoJR2" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:2yX9IXdpztUdSGYf3pNGqP6wRRQ= sha1:kuw+eGIf09v61ViL34LuYaILxwQ= Xref: csiph.com comp.lang.c:62882 Bartc writes: [...] > As an example of the quirks, take this simple program: > > int main(void) {} > > How many people know that it can also be written like this: > > int (main(void)) {} > > (with the extra parentheses)? At least one C compiler doesn't! I didn't know that, but I verified it by compiling with gcc and checking the syntax in the standard. Which compiler? Incidentally, cdecl recognizes int (main(void)) -- and any compiler that doesn't is non-conforming. > While the prototype for a function 'g', taking parameter type 'h', and > returning type 'f', can be written as: > > f(g(h)); > > Which happens to look exactly like a couple of nested function calls! > (This means it's not possible to write a simple syntax translator for > C.) The difference is that f and h are type names, which are syntactically distinct from identifiers. This: int(g(int)); is valid, but is more clearly written as int g(int); Parentheses are permitted in declarators for the same reason they're allowed in expressions: to specify grouping and improve clarity. C's declaration syntax is peculiar enough that the result can be confusing. In this case, int is a keyword, not an identifier, so there's no real ambiguity. If you use a typedef name: typedef int foo; foo(g(foo)); // or foo g(foo); it *seems* more ambiguous, but it isn't really. Typedefs were added to the language relatively late (I don't remember whether K&R1 had them), and they caused some syntactic problems. A typedef declaration effectively creates a new keyword, but only within the scope of the declaration -- except that the identifier can be redeclared in an inner scope. This makes it impossible to parse C without feedback from the symbol table. -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"