Re: #define and (brackets)
- From: "Alexander Grigoriev" <alegr@xxxxxxxxxxxxx>
- Date: Fri, 28 Nov 2008 07:22:31 -0800
That's what I have warned against. That separate preprocessing and
compilation is NOT the same as one-shot preprocessing and compilation.
Per ANSI C standard, there is NO re-pre-process (NO re-tokenization).
The compiler doesn't second-guess. It just follows the standard. May not
always be doing that, but in these cases it does.
By the way, I don't see what's the point in your stringizing example.
Operator # replaces the whole proprocessing token sequence for an argument
with a string.
"Alan Carre" <alan@xxxxxxxxxxxxxxxxx> wrote in message
news:eAOBdgWUJHA.5244@xxxxxxxxxxxxxxxxxxxxxxx
----
I think you guys a probably talking way over my head about multiple pass
compilation and re-tokenization expansion blah blah blah... But, for my
own sake at least, let's just look at a simple, very well-known fact about
the pre-processor for one minue:
#define STRIZE(x) #x // converts the argument into a
string.
#define _STRIZE_(x) STRIZE(x) // converts the pre-preocessed argument to
a string.
#define NUM -10
int main(int argc, ...)
{
puts(STRIZE(NUM));
puts(_STRIZE_(NUM));
puts(_STRIZE_(-NUM));
return 0;
}
Output:
--------
NUM
-10
--10
What can we learn from this?
This is how I see it:
=============
Case 1: STRIZE is passed a value x as NUM. The preprocessor allocates a
textual representation for x (*x* not NUM) as the value "NUM" (no quotes).
I just mean internally it's a string containing the word NUM. The macro
says #x which means to put quotations around this value so out pops "NUM"
in the source file. Case 1 explained.
Case 2: _STRIZE_ is passed x as NUM again. The preprocessor again creates
a textual representation for x, substituting it again as "NUM" (no
quotes!). Next, it must evaluate the macro but this time instead of #NUM
it is given STRIZE(NUM). At this point the preprocessor must decide what
to pass as x for STRIZE. So it is forced to try to expand NUM; to see if
it already exists as a macro (which it does) and that macro evaluates
to -10 (again textually, and internally). So the preprocessor then sets x
to "-10" (no quotes) passes that to STRIZE and finally evaluates #-10
which is "-10" in the source file (BTW. There are NO spaces before the
minus sign, you can double check if you don't believe me).
Case 3: In this case the preprocessor is passed -NUM into _STRIZE_ so x
has the textual representation -NUM. Again, it must re-evaluate this to
see if NUM is already a macro (and boy, if it didn't do that, and
treated -NUM as a *single token*, then NO macros would work at all!). So
the minus sign is not part of the token, only NUM is evaluated which
happens to be stored off as -10 [without any meaning! it's just what NUM
is when dereferenced from some string table]. Hence the expression -NUM
evaluates to --10 which is then passed into STRIZE for x and it winds up
as "--10" in the source file as expected (NO SPACES again).
============
So now then, the question is (or should be) "why does this work"?
int main(int argc,...)
{
printf("%d", -NUM);
}
Well I passed this through cl /E (preprocess to stdout) and got this as
the result:
int main(int argc, ...)
{
...lots of space...
printf("%d", --10);
return 0;
...lots of space...
}
Again, no spaces after the first minus sign, which should clearly have
generated a compiler error. CLEARLY. The above is cut and pasted from my
CMD box: It is byte-for-byte what is handed to the compiler from the
preprocessor. So it appears that there is a bug in the compiler in that it
must have re-interpreted the preprocessed file!
However it looks to me as though it is only smart enough to re-pre-process
1 level deep where, in this case, it can "see" that it would be better to
throw in a space there (at compilation time) because that's probably what
the programmer intended. Thanks cl.exe I wanted an error!
So there's your bug. The compiler shouldn't be in the business of
second-guessing the programmer's intentions with macros.
- Alan Carre
.
- Follow-Ups:
- Re: #define and (brackets)
- From: Alan Carre
- Re: #define and (brackets)
- References:
- #define and (brackets)
- From: Gerry Hickman
- Re: #define and (brackets)
- From: David Webber
- Re: #define and (brackets)
- From: Alan Carre
- Re: #define and (brackets)
- From: Igor Tandetnik
- Re: #define and (brackets)
- From: Alan Carre
- Re: #define and (brackets)
- From: Alan Carre
- Re: #define and (brackets)
- From: Igor Tandetnik
- Re: #define and (brackets)
- From: Alan Carre
- #define and (brackets)
- Prev by Date: Re: Visual Studio 2005 debuging question
- Next by Date: Re: #define and (brackets)
- Previous by thread: Re: #define and (brackets)
- Next by thread: Re: #define and (brackets)
- Index(es):
Relevant Pages
|