This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: c/4513: Preprocessor appears broken for the '#' operator
- To: nobody at gcc dot gnu dot org
- Subject: Re: c/4513: Preprocessor appears broken for the '#' operator
- From: Zack Weinberg <zack at codesourcery dot com>
- Date: 10 Oct 2001 05:26:03 -0000
- Cc: gcc-prs at gcc dot gnu dot org,
- Reply-To: Zack Weinberg <zack at codesourcery dot com>
The following reply was made to PR c/4513; it has been noted by GNATS.
From: Zack Weinberg <zack@codesourcery.com>
To: dgillies@graviton.com
Cc: Neil Booth <neil@daikokuya.demon.co.uk>, gcc-gnats@gcc.gnu.org
Subject: Re: c/4513: Preprocessor appears broken for the '#' operator
Date: Tue, 9 Oct 2001 22:22:33 -0700
On Wed, Oct 10, 2001 at 01:51:07AM -0000, dgillies@graviton.com wrote:
> #define STR2(X) #X
> #define MAKESTRING1(X) STR2(\) STR2(X)
> #define MAKESTRING2(X) STR2(X) STR2(\)
...
Expanding this to a complete test case:
#define STR2(X) #X
#define MAKESTRING1(X) STR2(\) STR2(X)
#define MAKESTRING2(X) STR2(X) STR2(\)
#define CONST 0300
MAKESTRING1(CONST)
MAKESTRING2(CONST)
2.95.4 branch, 20010902 snapshot:
tst.c:5: unterminated string or character constant
tst.c:5: possible real start of unterminated constant
# 1 "tst.c"
"\"
STR2(
0300
)
MAKESTRING2(CONST)
3.0.2 branch, 20010922 snapshot:
tst.c:5:1: warning: invalid string literal, ignoring final '\'
# 5 "tst.c"
"" "0300"
tst.c:6:1: warning: invalid string literal, ignoring final '\'
"0300" ""
Mainline matches 3.0.x.
Note the error messages in each case. The reason 2.95 does not expand
STR2 or MAKESTRING2 is that it processes #\ into "\", and interprets
that as the beginning of a multi-line string constant, running on into
the rest of the file. Since it's inside a string constant, of course
macros are not expanded.
3.0.x will not do this kind of violence to token boundaries. Instead,
it deletes the backslash in order to make a valid string literal out
of "\".
The C standard explicitly says that the result of stringification of a
single backslash is "\", _not_ "\\" as you might have expected. It
does then go on to say that, as "\" is not a valid string literal, the
behavior is undefined - so we are allowed to translate "\" into "\\"
if we want, or to do what 3.0 does, _or_ to do what 2.95 does.
I'm inclined to say that 3.0.2's behavior is preferable to 2.95.x's,
but that it's not worth trying to get 2.95 to do what 3.0 does (the
preprocessor was completely rewritten between 2.x and 3.x).
I'm also inclined to say that it is reasonable to dislike what 3.0
does, and I'll listen to discussion about whether or not #\ should
become "\\". However, I remember that there was a good reason why we
didn't do that in the first place. Neil, do you remember what it was?
zw