
Paul Mensonides wrote:
I was trying to summarize the notational conventions that were used throughout the document. I suppose that I could avoid the forward references here, and just introduce the notations when I introduce the concepts.
Probably better (I knew your notation already when starting proof-reading, so what you really need is a virgin reader).
Except for unused conditional compilation blocks, all tokens between directives are scanned for macro expansion.
Straight enough.
Well, I got complaints before about glossing over blue paint, so I'm trying to be explicit. At the same time, I'm trying to maintain the algorithm's point-of-view. How about:
If the current token is an identifier that refers to a macro, the preprocessor must check to see if it is painted. If an identifier token is painted, it means that the preprocessor will not attempt to expand it as a macro. In other words, the token itself is flagged as disabled and behaves like an identifier that does not correspond to a macro. This disabled flag is commonly referred to as "blue paint", and thus a token that is marked as disabled is called "painted." (The means by which an identifier token can become painted is describd below.) If the current token is painted, the preprocessor outputs the token and moves on to the next.
The paragraph has a *much* better flow now, IMO.
function-like macro has no formal parameters, and therefore any use of the stringizing operator is automatically an error.) The result of token-pasting in F's replacement list is
It's not clear to me why the stringizing operator leads to an error rather than a '#' character. Probably too much of a sidenote, anyway.
I don't know the rationale for why it is the way it is.
In this case, "therefore" is a bit strange...
I don't know. It is fairly cause-and-effect. If you use the stringizing operator in a nullary function-like macro, it is an error. For the same reason, if you use the stringizing operator in a non-nullary function-like macro without applying it to an instance of a formal parameter, it is an error.
No strong opinion, here. But while we're at it -- what about # define CHAOS_IP_HASH_I # ?
[Interleaved Invocations]
It is important to note that disabling contexts only exist during a _single_ scan. Moreover, when scanning passes the end of a disabling context, that disabling context no longer exists. In other words, the output of a scan results only in tokens and whitespace separations. Some of those tokens might be painted (and they remain painted), but disabling contexts are not part of the result of scanning.
(If they were, there would be no need for blue paint.)
Misses (at least) a reference to 16.3.4-1 (the wording "with the remaining tokens of the source" (or so) is quite nice there, so consider using something similar).
I have to clarify: I'm missing a hint (in the text not the examples) that tokens from outside the replacement list can form a macro invocation together with expansion output. The sentence from 16.3.4-1 is actually quite good.
I think that any need for this (i.e. such a hint) is symptomatic of trying to view macros like functions (e.g. F calls G, G returns 1 to F, F returns 1 to whatever called F). I'm in favor of doing anything that I can do to eradicate this preconception.
I disagree. If you don't want people to think of macros as functions it's important to point out the differences as clear as possible. It's quite easy to come up with a simple and stupid text replacement mechanism that does *not* have this behaviour without wasting a single thought on functions.
At the same time, it is worth noting that the syntax of macro invocations is dynamic. That is, a series of macro invocations cannot be parsed into a syntax tree and then evaluated. It can only parse one invocation at a time, and its result is basically appended to the input.
The terms 'invocation' and 'function-like macro' are probably much worse than wasting some words on how dynamic things really are... Regards, Tobias