Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.compilers > #1870 > unrolled thread
| Started by | Hans-Peter Diettrich <DrDiettrich1@netscape.net> |
|---|---|
| First post | 2017-05-13 08:49 +0200 |
| Last post | 2017-06-02 08:04 +0200 |
| Articles | 5 — 4 participants |
Back to article view | Back to comp.compilers
Preprocessing ## Hans-Peter Diettrich <DrDiettrich1@netscape.net> - 2017-05-13 08:49 +0200
Re: Preprocessing ## Hans-Peter Diettrich <DrDiettrich1@netscape.net> - 2017-05-15 11:28 +0200
Re: Preprocessing ## Kaz Kylheku <686-678-9105@kylheku.com> - 2017-05-15 13:41 +0000
Re: Preprocessing ## George Neuner <gneuner2@comcast.net> - 2017-05-15 11:31 -0400
Re: Preprocessing ## Hans-Peter Diettrich <DrDiettrich1@aol.com.dmarc.email> - 2017-06-02 08:04 +0200
| From | Hans-Peter Diettrich <DrDiettrich1@netscape.net> |
|---|---|
| Date | 2017-05-13 08:49 +0200 |
| Subject | Preprocessing ## |
| Message-ID | <17-05-003@comp.compilers> |
How is the C preprocessor assumed to handle the ## concatenation operator? In the Windows headers I found macros like #define foo(x) bar(##baz(x)) where an expansion into ... (baz ... doesn't make sense, because "(baz" is not a valid preprocessor token. Can somebody explain the meaning and handling of such constructs? DoDi [I would guess that some macro between ( and ## expanded to nothing. Or it could just be one of those text editing errors. -John]
[toc] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@netscape.net> |
|---|---|
| Date | 2017-05-15 11:28 +0200 |
| Message-ID | <17-05-004@comp.compilers> |
| In reply to | #1870 |
Am 13.05.2017 um 08:49 schrieb Hans-Peter Diettrich:
> How is the C preprocessor assumed to handle the ## concatenation operator?
>
> In the Windows headers I found macros like
> #define foo(x) bar(##baz(x))
> where an expansion into ... (baz ... doesn't make sense, because "(baz"
> is not a valid preprocessor token. Can somebody explain the meaning and
> handling of such constructs?
[John]
> [I would guess that some macro between ( and ## expanded to
> nothing.
The #define's leave no room for macros to the left of ##.
If, in above example, bar() were another macro, would the ## operator
stay literal part of the argument's token sequence?
E.g. with
#define bar(z) some_prefix z
would foo(suffix) expand into
some_prefix ##baz(suffix)
?
> Or it could just be one of those text editing errors. -John]
Not here. A comment before a couple of such #define's suggests, that
they are a workaround for the lack of variadic macros ("..." arguments).
DoDi
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <686-678-9105@kylheku.com> |
|---|---|
| Date | 2017-05-15 13:41 +0000 |
| Message-ID | <17-05-005@comp.compilers> |
| In reply to | #1870 |
On 2017-05-13, Hans-Peter Diettrich <DrDiettrich1@netscape.net> wrote: > How is the C preprocessor assumed to handle the ## concatenation operator? > > In the Windows headers I found macros like > #define foo(x) bar(##baz(x)) > where an expansion into ... (baz ... doesn't make sense, because "(baz" > is not a valid preprocessor token. Can somebody explain the meaning and > handling of such constructs? According to ISO C, if the result of the ## operator is an invalid token, the behavior is undefined. If you're making a compiler which will have to handle the unmodified header files from Microsoft platform development kits for Windows, you have little choice but to implement compatible preprocessing, which handles whatever constructs occur, in the same way. In other words, the actual meaning here is "whatever Visual C does". [Ugh. But I have to agree. -John]
[toc] | [prev] | [next] | [standalone]
| From | George Neuner <gneuner2@comcast.net> |
|---|---|
| Date | 2017-05-15 11:31 -0400 |
| Message-ID | <17-05-006@comp.compilers> |
| In reply to | #1870 |
On Sat, 13 May 2017 08:49:36 +0200, Hans-Peter Diettrich
<DrDiettrich1@netscape.net> wrote:
>How is the C preprocessor assumed to handle the ## concatenation operator?
It concatenate tokens *prior* to expansion. If the token references a
parameter of the current macro, the (text of the) parameter is
substituted, otherwise the token is simply copied.
e.g, #define foo(x) one ## two
... foo(help) => onetwo
#define foo(x) x ## _me
... foo(help) => help_me
>In the Windows headers I found macros like
> #define foo(x) bar(##baz(x))
>where an expansion into ... (baz ... doesn't make sense, because "(baz"
>is not a valid preprocessor token. Can somebody explain the meaning and
>handling of such constructs?
>
>DoDi
>[I would guess that some macro between ( and ## expanded to
>nothing. Or it could just be one of those text editing errors. -John]
I think John probably is correct that you've found typos. If it were
the result of a macro substitution, you would see it only in the
output of the preprocessor - it would not be visible in an input
header file.
Moreover, although I'm not 100% certain, I believe the preprocessor
does not substitute inside (it's own) preprocessor definitions, but
rather only substitutes into C code.
George
[toc] | [prev] | [next] | [standalone]
| From | Hans-Peter Diettrich <DrDiettrich1@aol.com.dmarc.email> |
|---|---|
| Date | 2017-06-02 08:04 +0200 |
| Message-ID | <17-06-003@comp.compilers> |
| In reply to | #1873 |
Am 15.05.2017 um 17:31 schrieb George Neuner: > On Sat, 13 May 2017 08:49:36 +0200, Hans-Peter Diettrich > <DrDiettrich1@netscape.net> wrote: > >> How is the C preprocessor assumed to handle the ## concatenation operator? > > It concatenate tokens *prior* to expansion. If the token references a > parameter of the current macro, the (text of the) parameter is > substituted, otherwise the token is simply copied. In a newer draft I found the constraint, that ## is an operator only if present in the replacement list (macro body), not from an argument. >> In the Windows headers I found macros like >> #define foo(x) bar(##baz(x)) Here the constraint is violated, ## is part of the argument and thus not recognized as a preprocessor operator. >> [I would guess that some macro between ( and ## expanded to >> nothing. Or it could just be one of those text editing errors. -John] > > I think John probably is correct that you've found typos. If it were > the result of a macro substitution, you would see it only in the > output of the preprocessor - it would not be visible in an input > header file. In the meantime I guess that this construct is a creative use of the preprocessor, when *also* used for some other postprocessor. The C compiler may never see the ## if bar(x) has an empty definition, with the argument unused. This seems to be the case with above example, unless a project or tool adds global definitions which result in a different definition of bar(x). The standard also includes an example #define hash_hash # ## # which expands into a new ## token, which *is not* the ## operator. This may or may not mean that ## is recognized and handled as a preprocessor operator *only if* it occurs in the replacement list (body) of a macro definition. Such a token is not accepted subsequently by a C compiler, but may be recognized by some other tool. Likewise the standard requires that a # operator must be followed by a macro argument, else it is not recognized as a preprocessor operator. This signals to me that the preprocessor is allowed to output token sequences which are not valid C code, but may be valid when processed by some other tool. > Moreover, although I'm not 100% certain, I believe the preprocessor > does not substitute inside (it's own) preprocessor definitions, but > rather only substitutes into C code. Right, immediate evaluation of # ## #, as a constant expression during macro definition, would result in a new ## token inside the replacement list, which would be recognized as another ## operator during a subsequent macro expansion. This were not the behaviour indicated by the description of above example. Thanks for your comments, without which I e.g. had guessed that constant expression evaluation were allowed during macro definition. DoDi
[toc] | [prev] | [standalone]
Back to top | Article view | comp.compilers
csiph-web