This is the mail archive of the
mailing list for the libstdc++ project.
Re: Fix for illegal token pasting in libstdc++ headers
- To: libstdc++ at sourceware dot cygnus dot com
- Subject: Re: Fix for illegal token pasting in libstdc++ headers
- From: Nathan Myers <ncm at cantrip dot org>
- Date: Tue, 4 Jul 2000 13:54:24 -0700
- References: <20000704093213.Y274@wolery.cumb.org>
- Reply-To: libstdc++ at sourceware dot cygnus dot com
On Tue, Jul 04, 2000 at 09:32:13AM -0700, Zack Weinberg wrote:
> If I may rant, this is one reason why writing "operator+" with no
> space between the keyword and the punctuator should be considered
> harmful. It gives the false impression that the entire is a single
> token, which in turn leads people to write code that does silly things
> like the above.
I shall rant as well, then. Zack's argument would lead to writing
std :: vector < int > v ( 3 ) ;
C++ isn't LISP. Punctuation parses differently in our brains,
and the C++ language is designed to take advantage of that. In
our brains, proximity equates to close relation, and our coding
style should use the fact.
Conceptually, "operator+" -- actually, "operator+(" -- really is
one token: it's the name of a function. Arguments from details
of yacc/lex processing are unhelpful because brains don't parse the
way yacc/lex do.
A similar argument has been made for preferring
on the basis that in the grammar, the "*" binds more tightly to
"f" than to "Foo". It is usually noted further that the convention
would prevent errors in the case of
Foo *f, *g;
The response is that in C++, we discourage defining two or more
variables in the same statement for that very reason, and because
it also leads to other errors such as declaring variables too
early, and failing to initialize them. Furthermore, consider
Foo *f = 0;
This appears to a sensible reader to be assigning zero into "*f",
rather than into f itself, as is actually occurring. In C++,
types are more important conceptually than in C, and a type is
recognized as a unit and not just a momentary construction. We
Lib_grumble::Foo* f = 0;
because it matches our mental contructions. "Lib_grumble::Foo"
contains no spaces because conceptually it's a single name, and
"Lib_grumble::Foo*" because conceptually it's a single type.
Wherever possible we put in spaces to separate conceptual units,
not lexical ones.
When compiler parsing differs substantively from natural mental
processing, errors are possible. We use coding conventions to prevent
cases of such confusion arising. While it might be best to design a
language in which mental and technical parsing details match exactly,
history has dictated that we base our syntax on C, instead. C has
many virtues, but sensible syntax design is not among them.
ncm at cantrip dot org