Path: csiph.com!goblin3!goblin.stu.neva.ru!news.misty.com!news.iecc.com!.POSTED.news.iecc.com!nerds-end From: Kaz Kylheku <686-678-9105@kylheku.com> Newsgroups: comp.compilers Subject: Re: C99 translation phases Date: Thu, 25 May 2017 19:03:45 +0000 (UTC) Organization: Aioe.org NNTP Server Lines: 63 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <17-05-012@comp.compilers> References: <17-05-011@comp.compilers> Injection-Info: miucha.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="6874"; mail-complaints-to="abuse@iecc.com" Keywords: C, design Posted-Date: 25 May 2017 23:34:19 EDT X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Xref: csiph.com comp.compilers:1879 On 2017-05-25, Hans-Peter Diettrich wrote: > The standard specifies translation phase 4 as: > "Preprocessing directives are executed, macro invocations are > expanded, and _Pragma unary operator expressions are executed. ..." > > Does this mean a strict sequence of these actions? No; the actions can be pipelined, etc. The successive stages describe the abstract model. The implementaton has to produce the same results as if those phases were obeyed. The result is *as if* those phases were successively applied. > At least this example seems to suggest a specific sequence: > > EXAMPLE In: > #define EMPTY > EMPTY # include > the sequence of preprocessing tokens on the second line is not > a preprocessing directive, because it does not begin with a # > at the start of translation phase 4, even though it will do so after the > macro EMPTY has been replaced. It's a sequence in exactly the same sense as chained function application: f(g(h(x))). In a functional language implementation, you can have non-strict evaluation semantics, so that it's possible for f to be called before x is evaluated; but the chaining, cannot be altered. C implementations do in fact pipe line some of the phases. Preprocessing might be one process which pipes output to a compiler, and then the assembler generating the binary code is another process, and these all run in parallel. The specific preprocessing situation you're referring to above is ruled out by explicit text in the C standard which has been there since 1989. Look for this: "The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one[.]" (Section "Rescanning and further replacement") Side note: the following has been added to the sentence at some point, due to the inline _Pragma feature being added to the language: "but all pragma unary operator expressions within it are then processed as specified in
" That the first sentence is necessary because the processing of directives and macro replacement both happen in the *same* translation phase! There isn't a separate translation phase for executing preprocessing directives and for expanding macros. In the draft that I'm looking at, it is translation phase 4, in which all of this happens: 4. Preprocessing directives are execute, macro invocations are expanded, and _Pragma unary operator expressions are executed. There is no order among these; those are the activities which happen in phase 4 in response to the syntax which occurs and its evaluation order. From the description of translation phase 4 alone, it is not clear that macros do not generate preprocessing directives.