Full name of submitter (unless configured in github; will be published with the issue): Yin Xinyu
Reference (section label): [cpp.replace.general]
Issue description:
[cpp.replace.general]/14 says:
If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the program is ill-formed.
The intention is possibly avoiding multi-line macro invocations that cross text lines and preprocessing directives ([cpp.pre]). Consider:
// ill-formed
#define FOO(...)
FOO( // text-line
#include <iostream> // pp-directive
) // text-line
Although it's impossible to perform a multi-line macro invocation starting at a preprocessing directive, the current wording would accept the following
// well-formed
#define FOO(...)
FOO( // text-line
#bluh ) bluh // pp-directive
since the conditionally-supported directive #bluh ) bluh is not within the list of arguments consisting of merely #bluh.
Implementations have no consensus on how to deal with this case (godbolt). By the way they have not even diagnosed the first example as ill-formed.
This can result in an even weirder situation, although results are all ill-formed. Consider:
#define FOO(...)
#define LPAREN (
#define NIL
FOO( // text-line
#if LPAREN X ) NIL // pp-directive
#endif // pp-directive
and
#define FOO(...)
#ifdef X
FOO( // text-line
#else )) // pp-directive
#endif // pp-directive
It's hard to tell what would happen, where X may be in different branches.
To avoid these complex and anti-intuitive circumstances, we'd better edit the wording of [cpp.replace.general]/14 to forbid these cases.
If an application such as stringization is needed, the following is well-formed.
#define STR(x) STR2(x)
#define STR2(x) #x
#define HASH #
#define NIL
STR(
HASH include <iostream>
)
STR(
NIL #include <iostream>
)
The arguments in STR2 is safe, considering [cpp.rescan]/4
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one, but all pragma unary operator expressions within it are then processed as specified in [cpp.pragma.op] below.
Suggested resolution:
Change [cpp.replace.general]/14:
If there are sequences of preprocessing tokens within the list of arguments that , along with all preprocessing tokens immediately following them, would otherwise act as preprocessing directives, the program is ill-formed.
Full name of submitter (unless configured in github; will be published with the issue): Yin Xinyu
Reference (section label): [cpp.replace.general]
Issue description:
[cpp.replace.general]/14 says:
The intention is possibly avoiding multi-line macro invocations that cross text lines and preprocessing directives ([cpp.pre]). Consider:
Although it's impossible to perform a multi-line macro invocation starting at a preprocessing directive, the current wording would accept the following
since the conditionally-supported directive
#bluh ) bluhis not within the list of arguments consisting of merely#bluh.Implementations have no consensus on how to deal with this case (godbolt). By the way they have not even diagnosed the first example as ill-formed.
This can result in an even weirder situation, although results are all ill-formed. Consider:
and
It's hard to tell what would happen, where
Xmay be in different branches.To avoid these complex and anti-intuitive circumstances, we'd better edit the wording of [cpp.replace.general]/14 to forbid these cases.
If an application such as stringization is needed, the following is well-formed.
The arguments in
STR2is safe, considering [cpp.rescan]/4Suggested resolution:
Change [cpp.replace.general]/14: