This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Proposal for extension to GCC


Whoops, I take it back. Forget I suggested this.

I came up with the idea late last night when I was (frustratedly) working on a
C++ parser/editor.

As soon as I woke up this morning (does 11 a.m. count as morning?) I realised
that this would break existing code. e.g.
	(int)(x, y, z); // means evaluate x, y, and z, then cast z to an int.

It would still be nice if there was an alternative syntax though, especially if
it was modelled on the (struct X){..., ..., ...} syntax.

Ted Clancy.


----------  Forwarded Message  ----------
Subject: Proposal for extension to GCC
Date: Fri, 18 Aug 2000 22:21:16 -0700
From: Ted Clancy <clancyt@look.ca>


Hello,

I know that proposing an extension to GCC is not a matter taken lightly, I hope
that what I write here will be seen as a beneficial contribution, which solves
many problems, without introducing any new ones.

My proposal is that the syntax for a function-style cast be changed from:
	simple-type-specifier ( expression-listopt )
to:
	(simple-type-specifier) ( expression-listopt )

(For compatibility with old code, and conformance with the Standard, the old
syntax would have to be kept too, of course.)

This would only require simple changes to the YACC file, and would be more
consistent with the (struct X){..., ..., ...} syntax of C99 for anonymous
objects.

But the question you're all asking is WHY???, so here comes the explaination:

We're probably all familiar with the ambiguity that
	simple-type-specifier(expression-listopt)
can be either a function-style cast expression, or part of a declaration. e.g. 

	int (*a);  // Could mean "dereference 'a' and cast to int",
		// or could declare a pointer to an int.

The standard specifies that this ambiguity should be resolved as a declaration.

This amiguity causes some big problems.

1) First of all, C++ is NOT YACCable. Determining whether or not a statement is
an expression or a declaration requires an infinite amount of lookahead. For
example:
	int (*a), b, c, d, e, f, g, h, i, j;  //This is a declaration.
	int (*a), b, c, d, e, f, g, h, i, j, k+l; //This is an expression.

This should disturb us for a couple reasons. For a start, a language which
requires infinite lookahead is just offensive. More pertinently, it should
disturb us because GCC is based on YACC.

2) I cannot define an object 'b' using:

	B b(A(), A());

because it's parsed as a function declaration, not an object declaration.

The token sequence 'A()' could be a simple-type specifier, like saying
	B b(int, int);
or the token sequence 'A()' could be the construction of a temporary object.

I want it to be the latter, but it's interpreted as the former.

More dramatically, 
	B b(A(), A(1));
causes a parser error in GCC, and this is recognised as a notable bug on the GCC
webpages.


Now, if C++'s syntax for a function-style cast was 
	(simple-type-specifier) ( expression-listopt )
instead of 
	simple-type-specifier ( expression-listopt )
there would be no ambiguity. C++ would be YACCable. We'd wouldn't have that bug.
(And it would be more consistent with C99). In my opinion, that's how it
should have been from the start. Unfortunately, we can't change C++'s history,
and we have to live with it.

The C++ committee's big mistake, in my opinion, was to make such ambiguities
default to declarations. It's already easy to specify that you want the
ambiguous token sequence to be a declaration. Just change
	int (*a), b, c;
to
	auto int (*a), b, c;  //explicitly made a declaration.
And just change
	B b(A(), A());
to 
	B b(A, A);  //explicitly made a function declaration.

It's much harder to specifiy that you want the ambiguous token sequence to be
an expression. Therefore, the default should have been to interpret the token
sequence as an expression.

If we allow the syntax
	(simple-type-specifier) ( expression-listopt )
then it is now possible to explicitly specify that you want those ambiguities
to be expressions. You can say:
	(int)(*a);		// an expression.
	(int)(*a), b, c;  	// an expression.
	B b((A)(), (A)());	// an object declaration.
	B b((A)(), (A)(1));	 	// no parse error!!


So basically, I propose adopting the syntax
	(simple-type-specifier) ( expression-listopt )
for the following reasons:
	1) Allows explicit disambuguation.
 	2) That's the way it should have been.
	3) It's fits better with C99 syntax.
	4) It only requires changing the YACC file.

I don't know if anyone has proposed this before, and I apologise if it has. For
all I know, this could be a common suggestion. If not, I ask you to consider it.

Ted Clancy.
s341282@student.uq.edu.au
-------------------------------------------------------

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]