|
Boost : |
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2005-07-15 04:31:14
> -----Original Message-----
> From: boost-bounces_at_[hidden]
> [mailto:boost-bounces_at_[hidden]] On Behalf Of Dave Steffen
> I agree that macros are code writers, no arguments there.
>
> I also agree that macros are not part of the C++ syntax model at all.
> No question. From the C++ point of view, macros are some
> sort of alien life form that shows up, does something that's
> hopefully useful and correct (but might not be), and then
> goes away, leaving a trail of slime in its wake. In the
> presence of macros, don't go after the cat. :-) :-)
I disagree with just about all of this except the first two sentences. There is
nothing wrong with macros. There is something wrong with trying to make macros
look like non-macros.
> They're so unpleasant that Bjarne "Our Founder" Stroustrup
> has always encouraged minimizing the use of the preprocessor,
And Bjarne is wrong, IMO. How much the preprocessor should be used is entirely
dictated by whether preprocessor use is a better solution than the alternatives.
It isn't even a case of "last resort".
> restricting its use to the #include thing, and IIRC would
> like to come up with a language extension eliminating even
> that. (Isn't there a "modules" language extension being
> discussed for C++0X?) A preprocessorless C++ would certainly
> be A Good Thing (that may never happen, but that's a
> different discussion).
That would be a terrible thing. Having a standard source code manipulation tool
that is above the syntax of the language is incredibly useful.
> I would claim that while macros are indeed aliens that
> sometimes display unpleasant behavior (e.g. unreadable error
> messages when misused),
Trivially fixed by preprocessing in a separate pass--which is something you
can't do with templates.
> one _can_ assign some sort of C++
> syntactic meaning to their use.
But we shouldn't. We should assign syntactic meaning to what they result in.
FOREACH is not a looping construct. It is a looping construct *writer*, and
that is exactly how it should be viewed. The point being, what a macro expands
to should always be a fundamental part of the interface of a macro. The "return
value" of a macro is code.
> For example: the FOREACH macro is clearly meant to take the
> syntactic place of "for (bim; bam; boom++)", and anywhere you
> can put that, you can put an appropriate FOREACH. This is an
> good example of your "macro only accomplishes *part* of its
> function--it only generates
> *part* of the code", and you follow it with the rest.
This is an example of where it is necessary, or, at least, superior to do so.
Not because of the resulting syntax, but because of the caveats in the syntax if
it was the other way (e.g. you'd have to encode open commas).
> Now: I would argue strongly that, to the extent that a macro
> is intented to be used in some syntactic C++ context, it
> should do its best to fit in to that context.
I couldn't disagree with this mentality more. A macro should *never* be
designed to "fit into some syntactic C++ context". It may be defined to fit
into some C++ _semantic_ context, but only the result of a macro should be
defined to fit into a syntactic context. The concept of macros as an underlying
C++ syntactic construct is pure evil.
> BOOST_PARAMETER_KEYWORD(tag_namespace,
> name) should mandate a semicolon, just as function
> declarations and class definitions do.
Function definitions don't, and not all member functions should be implicitly
marked as inline by being defined inside a class definition.
> Yes: "Macros are not functions. Invocations are are not
> expressions, they are not statements, and they are not
> declarations." But they are going to sit side-by-side with
> our expressions, statements, and declarations.
No, they sit side-by-side, create, and interleave with our expressions,
statements, and declarations.
> I think you
> want to intentionally design macros _not_ to conform to the
> syntax of their intended use, so that anyone who uses them
> sees, loud and clear, WARNING: ALIEN MACRO INVOCATION. THIS
> IS NOT C++. DO NOT GO AFTER SHIP'S CAT.
I have a problem with several prevailing viewpoints. One of them is that macros
are evil. The reason that this is a prevailing viewpoint is precisely because
people keep trying to make them fit into the syntax model, instead viewing them
as a separate syntax model that is overlaid. Nearly all macro-related problems
stem from this attempted facade.
> I don't think that helps. I don't think it is useful to
> intentionally build libraries where, from the user's point of
> view, some things obey
> C++ grammar and some things arbitrarily don't.
It isn't arbitrary. Some things are written in the language understood by the
preprocessor. All constructs written in that language should be assumed by
users *not* to fit into the C++ grammar.
> Yes, those that don't
> obey the usual syntax make me think "Ah yes, that's a macro,
> am I using it correctly?" But we already do that because of
> the ALL_CAPS_MACRO convention, which flags things that C++
> programmers quickly learn to approach with caution. And if
> the correct syntax is unclear ("Do I follow this macro with a
> semicolon, statement block, or mystic runes?"), isn't it more
> likely we'll screw it up?
That is what documentation is for, which is no different than any other
construct. The syntax of a function call (a real function call) says almost
nothing about how the function can be used and what it does. It only shows how
a function call can be syntactically formed. The rest is the semantic effect of
the function. With a macro, what the invocation results in is the semantic
effect of the macro--which should be documented if the macro is an interface.
I.e. the semantic effect of a macro *is* the syntactic effect on the program,
and it should be documented from that viewpoint. The semantic intention of the
resulting code should also be documented (obviously).
Regards,
Paul Mensonides
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk