Velocity Reviews - Computer Hardware Reviews

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

Reply
Thread Tools

preprocessor q: impossible macro?

 
 
Eric
Guest
Posts: n/a
 
      07-18-2005
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")....

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?
Eric


 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      07-18-2005
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
 
 
 
 
Charles Mills
Guest
Posts: n/a
 
      07-18-2005
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

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      07-18-2005
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
 
Reply With Quote
 
Charles Mills
Guest
Posts: n/a
 
      07-18-2005


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


gcc
pasting ""#"" and "STR" does not give a valid preprocessing token

The standard says that token pasting must result in a valid C token.

-Charlie

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      07-18-2005
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

>
>
> gcc
> pasting ""#"" and "STR" does not give a valid preprocessing token
>
> The standard says that token pasting must result in a valid C token.


I don't have a copy of the _old_ C standard handy, but the C++ Standard
has the sub-clause 16.3.1 (and C99 has 6.10.3.1), which essentially says
that operators # and ## are only acted upon after *all* substitutions have
taken place. So, your version of gcc is *buggy* if it doesn't compile the
code I posted, it ought to rescan the substitution (according to 16.3.4)
until no macro is left unsubstituted.

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
 
Reply With Quote
 
Rob Williscroft
Guest
Posts: n/a
 
      07-18-2005
Victor Bazarov wrote in news:ASSCe.19456$Tf5.2888
@newsread1.mlpsca01.us.to.verio.net in comp.lang.c++:

>
> Yes, you need an indirect "stringizing" macro for that.
>
> #define STR(x) #x
> #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.

> #define IDB_BUTTON 225
>
> #include <stdio.h>
>
> int main(void) {
> printf("Got %s\n", MYMACRO(IDB_BUTTON));
> }


Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      07-18-2005
Rob Williscroft wrote:
> Victor Bazarov wrote in news:ASSCe.19456$Tf5.2888
> @newsread1.mlpsca01.us.to.verio.net in comp.lang.c++:
>
>
>>Yes, you need an indirect "stringizing" macro for that.
>>
>> #define STR(x) #x
>> #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...
Also, see my reply to Charles Mills. The code is valid.

>> #define IDB_BUTTON 225
>>
>> #include <stdio.h>
>>
>> int main(void) {
>> printf("Got %s\n", MYMACRO(IDB_BUTTON));
>> }

>
>
> Rob.


V
 
Reply With Quote
 
Me
Guest
Posts: n/a
 
      07-18-2005
Eric wrote:
> 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")....
>
> 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 (see the other responses to this thread) but if you're programming
Windows like I suspect you are, you don't even need to do this, you can
just use the MAKEINTATOM(IDB_BUTTON) macro provided in windows.h which
does something more efficient based on a feature of the OS.

 
Reply With Quote
 
Rob Williscroft
Guest
Posts: n/a
 
      07-18-2005
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



Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
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