Re: #define and (brackets)
- From: "Alan Carre" <alan@xxxxxxxxxxxxxxxxx>
- Date: Fri, 28 Nov 2008 21:46:49 +0700
"Igor Tandetnik" <itandetnik@xxxxxxxx> wrote in message
news:OD73zvqTJHA.4744@xxxxxxxxxxxxxxxxxxxxxxx
"Alan Carre" <alan@xxxxxxxxxxxxxxxxx> wrote in message
news:O2UQLypTJHA.1332@xxxxxxxxxxxxxxxxxxxx
Correction. On it's own it works, but in a macro it doesn't:
#define SHRX -10
#define SHRY -20
#define SHRINK(rect) rect.DeflateRect(-6-SHRX,6-SHRY)
You get a compile error.
This looks like a bug in MSVC compiler. This program:
Boy, go away for a day or 2 and all hell breaks loose!
----
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: Hendrik Schober
- Re: #define and (brackets)
- From: Igor Tandetnik
- Re: #define and (brackets)
- From: Alex Blekhman
- Re: #define and (brackets)
- From: Alexander Grigoriev
- 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
- #define and (brackets)
- Prev by Date: Re: Conditional compiling according to C++ compiler version (Express or Professional)
- Next by Date: Visual Studio 2005 debuging question
- Previous by thread: Re: #define and (brackets)
- Next by thread: Re: #define and (brackets)
- Index(es):
Relevant Pages
|
Loading