Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > preprocessor q: impossible macro?

Reply
Thread Tools

preprocessor q: impossible macro?

 
 
Victor Bazarov
Guest
Posts: n/a
 
      07-18-2005
Rob Williscroft wrote:
> Victor Bazarov wrote in news:JoUCe.19463$Tf5.10002
> @newsread1.mlpsca01.us.to.verio.net in comp.lang.c++:
>
>
>>>> #define MYMACRO(num) "#" ## STR(num)
>>>>
>>>
>>>
>>>You don't need the ## above as strings concatinate anyway:
>>>
>>> #define MYMACRO(num) ( "#" STR(num) )
>>>
>>>Also AIUI using ## to concatinate 2 tokens that don't then
>>>make a valid preprocessor token is illegal.

>>
>>I don't understand this sentence. Perhaps you could rephrase...

>
>
> Here's n example of the use of ## pehraps it will help:
>
> #include <iostream>
> #include <ostream>
>
> #define STR( x ) #x
> #define XSTR( x ) "X" STR( x )
>
> #define PSTR_2( x, y ) x ## STR( y )
> #define PSTR( x, y ) PSTR_2(x, y )
>
>
> int main()
> {
> std::cout << STR(i) << std::endl;
> std::cout << PSTR(X,i) << std::endl;
> }
>
> The 2 tokens you are attempting to paste are " and STR, "STR
> is not a valid preprocessor token.
>
>
>>Also, see my reply to Charles Mills. The code is valid.
>>

>
>
> You can find this in the Standard
>
> 16.3.3 The ## operator
>
> ...
>
> If the result is not a valid preprocessing token,
> the behavior is undefined


Yes, how is that applicable here? Did you read my reply to Charles?

V
 
Reply With Quote
 
 
 
 
Rob Williscroft
Guest
Posts: n/a
 
      07-18-2005
Victor Bazarov wrote in news:q%UCe.19466$Tf5.9220
@newsread1.mlpsca01.us.to.verio.net in comp.lang.c++:

>> You can find this in the Standard
>>
>> 16.3.3 The ## operator
>>
>> ...
>>
>> If the result is not a valid preprocessing token,
>> the behavior is undefined

>
> Yes, how is that applicable here? Did you read my reply to Charles?
>
>


Yes, your argument is incorrect, reread 16.3.3, the "*all*" in
your paraphrasing ("essentialy says ...") is wrong. Only macro
paramiters are expanded before ## is used to paste tokens.

Not that that would matter anyway, the token on the left of the ##
is a quote ("), and a quote is a single token, its *never* part
of another token. Which violates the above cut&paste from the
Standard.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
 
 
 
Charles Mills
Guest
Posts: n/a
 
      07-18-2005
Rob Williscroft wrote:
> Victor Bazarov wrote in news:q%UCe.19466$Tf5.9220
> @newsread1.mlpsca01.us.to.verio.net in comp.lang.c++:
>
> >> You can find this in the Standard
> >>
> >> 16.3.3 The ## operator
> >>
> >> ...
> >>
> >> If the result is not a valid preprocessing token,
> >> the behavior is undefined

> >
> > Yes, how is that applicable here? Did you read my reply to Charles?
> >
> >

>
> Yes, your argument is incorrect, reread 16.3.3, the "*all*" in
> your paraphrasing ("essentialy says ...") is wrong. Only macro
> paramiters are expanded before ## is used to paste tokens.
>
> Not that that would matter anyway, the token on the left of the ##
> is a quote ("), and a quote is a single token, its *never* part
> of another token. Which violates the above cut&paste from the
> Standard.
>
> Rob.
> --
> http://www.victim-prime.dsl.pipex.com/


I think you mean a string literal is a single token, right?
So pasting two string literals like:
"a" ## "b"
would create the token:
"a""b"
which is an invalid token.
Another example would be pasting the tokens c and ++
c ## ++
creates the token
c++
which is not a valid C token

-Charlie

 
Reply With Quote
 
Rob Williscroft
Guest
Posts: n/a
 
      07-18-2005
Charles Mills wrote in news:1121724926.368427.251760
@g49g2000cwa.googlegroups.com in comp.lang.c++:

>
> I think you mean a string literal is a single token, right?


I didn't, but I was wrong . Thanks for the correction.

> So pasting two string literals like:
> "a" ## "b"
> would create the token:
> "a""b"
> which is an invalid token.


Not so sure about that, which is maybe why Victor, believes
his interpritation is correct, if valid and *all* tokens were
expanded prior to ## doing its thing, then Victors code would
be valid. But that isn't what the Standard says, but it possibly
is how many C++ preprocessors currently work.

> Another example would be pasting the tokens c and ++
> c ## ++
> creates the token
> c++
> which is not a valid C token
>


Agreed.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
Greg
Guest
Posts: n/a
 
      07-19-2005


Victor Bazarov wrote:
> Charles Mills wrote:
> > Victor Bazarov wrote:
> >
> >>Charles Mills wrote:
> >>
> >>>Victor Bazarov wrote:
> >>>[..]
> >>>
> >>>> #define STR(x) #x
> >>>> #define MYMACRO(num) "#" ## STR(num)
> >>>>
> >>>> #define IDB_BUTTON 225
> >>>>
> >>>> #include <stdio.h>
> >>>>
> >>>> int main(void) {
> >>>> printf("Got %s\n", MYMACRO(IDB_BUTTON));
> >>>> }
> >>>>
> >>>>V
> >>>
> >>>
> >>>The above solution does not compile. [..]
> >>
> >>On what compiler? What is the error message?
> >>
> >>V

>
> IOW, the result of 'MYMACRO(IDB_BUTTON)' yields
>
> "#" ## STR(225)
>
> which in turn, after rescanning yields
>
> "#" ## #225
>
> which then yields
>
> "#" ## "225"
>
> And two tokens are concatenated. Relying on the catenation of strings
> is OK, I suppose. I just don't like it, and use ## explicitly.
>
> BTW, Comeau online thingy gets it right in all modes, VC++ gets it right,
> and I am betting, countless others get it right, I am just too lazy to
> check.
>
> V


Your code may compile but its output is not correct. The preprocessed
output of the printf statement in the above example is:

std:rintf("Got %s\n", "#""IDB_BUTTON" );

whereas the corrrect result would be:

std:rintf("Got %s\n", "#225" );

or its equivalent. Omitting the ## token pasting operator does yield
the correct result. Another solution would be to use slightly different
macros:

#define STR(num) "#" ## #num
#define MYMACRO(num) STR(num)

In both of these cases the preprocessed output is:

std:rintf("Got %s\n", "#" "225" );

As others have noted, the compiler will concatenate adjacent string
literals, making this output match the correct result;

Greg

 
Reply With Quote
 
Heinz Ozwirk
Guest
Posts: n/a
 
      07-19-2005
"Eric" <(E-Mail Removed)> schrieb im Newsbeitrag
news:dbgt23$f33$(E-Mail Removed)...
> Hello all,
> I've got this line of given code (cannot change this; wizard-generated,
> but value may change someday):
> #define IDB_BUTTON 225
>
> Somewhere in the code I found / need this:
> ....somefunction("#225")....


If those defines and functions are what I think they are, you should have a
look at MAKEINTRESOURCE in your compiler's/API's documentation.

Heinz


 
Reply With Quote
 
noblesantosh@yahoo.com
Guest
Posts: n/a
 
      07-19-2005


Charles Mills wrote:
> Victor Bazarov wrote:
> > Eric wrote:
> > > I've got this line of given code (cannot change this; wizard-generated, but
> > > value may change someday):
> > > #define IDB_BUTTON 225
> > >
> > > Somewhere in the code I found / need this:
> > > ....somefunction("#225")....
> > >
> > > This string in the function call is the same number like in the define, but
> > > the constant wasn't used. Because for future changes and for readability I
> > > wanted to create this string with a preprocessor macro like this:
> > > ....somefunction(MYMACRO(IDB_BUTTON))....
> > >
> > > I didn't get such a macro to work. I tried:
> > > #define MYMACRO(num) "#" #num
> > > but this only yields to
> > > ....somefunction("#" "IDB_BUTTON")....
> > > I also tried with the token-pasting operator (##) etc.
> > >
> > > Is this possible at all?

> >
> > Yes, you need an indirect "stringizing" macro for that.
> >
> > #define STR(x) #x
> > #define MYMACRO(num) "#" ## STR(num)
> >
> > #define IDB_BUTTON 225
> >
> > #include <stdio.h>
> >
> > int main(void) {
> > printf("Got %s\n", MYMACRO(IDB_BUTTON));
> > }
> >
> > V

>
> The above solution does not compile. Token pasting is not necessary
> since adjacent string literals are pasted.
>
> #define STR(x) #x
> #define MYMACRO(num) "#" STR(num)
>
> #define IDB_BUTTON 225
>
> #include <stdio.h>
>
> int main(void) {
> printf("Got %s\n", MYMACRO(IDB_BUTTON));
> }
>
> -Charlie


Charlie, your code doesn't compile ...

[ysantosh@IndLexx testprogs]$ gcc prog1.c
prog1.c:10:28: warning: pasting ""#"" and "STR" does not give a valid
preprocessing token
prog1.c: In function `main':
prog1.c:10: parse error before `STR'

--santosh

 
Reply With Quote
 
noblesantosh@yahoo.com
Guest
Posts: n/a
 
      07-19-2005


http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Charles Mills wrote:
> > Victor Bazarov wrote:
> > > Eric wrote:
> > > > I've got this line of given code (cannot change this; wizard-generated, but
> > > > value may change someday):
> > > > #define IDB_BUTTON 225
> > > >
> > > > Somewhere in the code I found / need this:
> > > > ....somefunction("#225")....
> > > >
> > > > This string in the function call is the same number like in the define, but
> > > > the constant wasn't used. Because for future changes and for readability I
> > > > wanted to create this string with a preprocessor macro like this:
> > > > ....somefunction(MYMACRO(IDB_BUTTON))....
> > > >
> > > > I didn't get such a macro to work. I tried:
> > > > #define MYMACRO(num) "#" #num
> > > > but this only yields to
> > > > ....somefunction("#" "IDB_BUTTON")....
> > > > I also tried with the token-pasting operator (##) etc.
> > > >
> > > > Is this possible at all?
> > >
> > > Yes, you need an indirect "stringizing" macro for that.
> > >
> > > #define STR(x) #x
> > > #define MYMACRO(num) "#" ## STR(num)
> > >
> > > #define IDB_BUTTON 225
> > >
> > > #include <stdio.h>
> > >
> > > int main(void) {
> > > printf("Got %s\n", MYMACRO(IDB_BUTTON));
> > > }
> > >
> > > V

> >
> > The above solution does not compile. Token pasting is not necessary
> > since adjacent string literals are pasted.
> >
> > #define STR(x) #x
> > #define MYMACRO(num) "#" STR(num)
> >
> > #define IDB_BUTTON 225
> >
> > #include <stdio.h>
> >
> > int main(void) {
> > printf("Got %s\n", MYMACRO(IDB_BUTTON));
> > }
> >
> > -Charlie

>
> Charlie, your code doesn't compile ...
>
> [ysantosh@IndLexx testprogs]$ gcc prog1.c
> prog1.c:10:28: warning: pasting ""#"" and "STR" does not give a valid
> preprocessing token
> prog1.c: In function `main':
> prog1.c:10: parse error before `STR'
>
> --santosh


 
Reply With Quote
 
Jirka Klaue
Guest
Posts: n/a
 
      07-19-2005
Victor Bazarov:
....
> IOW, the result of 'MYMACRO(IDB_BUTTON)' yields
>
> "#" ## STR(225)
>
> which in turn, after rescanning yields
>
> "#" ## #225
>
> which then yields
>
> "#" ## "225"
>
> And two tokens are concatenated. Relying on the catenation of strings
> is OK, I suppose. I just don't like it, and use ## explicitly.


The concatenation with ## yields "#""225" which is not a valid
preprocessing token.

> BTW, Comeau online thingy gets it right in all modes, VC++ gets it right,
> and I am betting, countless others get it right, I am just too lazy to
> check.


It's not relevant what any compiler considers "right".

Jirka
 
Reply With Quote
 
Eric
Guest
Posts: n/a
 
      07-19-2005
Hi Victor, Charles, Greg, Jirka, noblesantosh, Rob

Thanks for your valuable feedback and the infos about tokens. I don't know
what's the exact difference to what I have made, but like you said, it's
obviously impossible to do it with one single macro. Probably that's why I
couldn't get my version to work.

I know omitted the ## like mentioned in the thread, which yields to "#"
"225", which works fine.

Follow-up question: Is it possible to create a macro that yields to exactly
"#225" after preprocessing?

Eric



"Victor Bazarov" <(E-Mail Removed)> wrote in message
news:ASSCe.19456$(E-Mail Removed)01.us.to .verio.net...
> Eric wrote:
>> I've got this line of given code (cannot change this; wizard-generated,
>> but value may change someday):
>> #define IDB_BUTTON 225
>>
>> Somewhere in the code I found / need this:
>> ....somefunction("#225")....
>>
>> This string in the function call is the same number like in the define,
>> but the constant wasn't used. Because for future changes and for
>> readability I wanted to create this string with a preprocessor macro like
>> this:
>> ....somefunction(MYMACRO(IDB_BUTTON))....
>>
>> I didn't get such a macro to work. I tried:
>> #define MYMACRO(num) "#" #num
>> but this only yields to
>> ....somefunction("#" "IDB_BUTTON")....
>> I also tried with the token-pasting operator (##) etc.
>>
>> Is this possible at all?

>
> Yes, you need an indirect "stringizing" macro for that.
>
> #define STR(x) #x
> #define MYMACRO(num) "#" ## STR(num)
>
> #define IDB_BUTTON 225
>
> #include <stdio.h>
>
> int main(void) {
> printf("Got %s\n", MYMACRO(IDB_BUTTON));
> }
>
> V



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
impossible to delete file because it is impossible to take ownership Devvie Nuis Computer Support 21 04-20-2009 02:07 AM
Making the simple impossible and the impossible unthinkable... xfx.publishing@gmail.com Perl Misc 5 06-30-2006 11:50 AM
preprocessor q: impossible macro? Eric C Programming 21 07-19-2005 12:47 PM
Compiler error occurred when try to use a flexible template expression in preprocessor definesCompiler error occurred when try to use a flexible template expression in preprocessor defines snnn C++ 6 03-14-2005 04:09 PM
preprocessor, token concatenation, no valid preprocessor token Cronus C++ 1 07-14-2004 11:10 PM



Advertisments