By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,130 Members | 1,365 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,130 IT Pros & Developers. It's quick & easy.

preprocessor q: impossible macro?

P: n/a
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
Jul 23 '05 #1
Share this Question
Share on Google+
21 Replies


P: n/a
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
Jul 23 '05 #2

P: n/a
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

Jul 23 '05 #3

P: n/a
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
Jul 23 '05 #4

P: n/a


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

Jul 23 '05 #5

P: n/a
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
Jul 23 '05 #6

P: n/a
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/
Jul 23 '05 #7

P: n/a
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
Jul 23 '05 #8

P: n/a
Me
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.

Jul 23 '05 #9

P: n/a
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/
Jul 23 '05 #10

P: n/a
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
Jul 23 '05 #11

P: n/a
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/
Jul 23 '05 #12

P: n/a
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

Jul 23 '05 #13

P: n/a
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/
Jul 23 '05 #14

P: n/a


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::printf("Got %s\n", "#""IDB_BUTTON" );

whereas the corrrect result would be:

std::printf("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::printf("Got %s\n", "#" "225" );

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

Greg

Jul 23 '05 #15

P: n/a
"Eric" <ba********@kull.ch.nospam.me.com> schrieb im Newsbeitrag
news:db**********@news.hispeed.ch...
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
Jul 23 '05 #16

P: n/a


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

Jul 23 '05 #17

P: n/a


no**********@yahoo.com 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


Jul 23 '05 #18

P: n/a
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
Jul 23 '05 #19

P: n/a
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" <v.********@comAcast.net> wrote in message
news:AS******************@newsread1.mlpsca01.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

Jul 23 '05 #20

P: n/a
Hi Me

The macro MAKEINTATOM yields to
(LPTSTR)((ULONG_PTR)((WORD)(225)))
Which is not quite the same, but might work in the context you mentioned.
(I'm using it with the Win32 API function LoadImage.)
The code was given and I didn't want to change it, but you're right, this is
the recommended way to do it.
Although the documentation says to use the macro MAKEINTRESOURCE which
yields to:
(LPSTR)((ULONG_PTR)((WORD)(225)))
Both LPSTR and LPTSTR are defined as char *.

Eric
"Me" <an*****************@yahoo.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
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.

Jul 23 '05 #21

P: n/a
Hi Heinz

Thanks for your feedback. See my answer to "Me" above.
You're right, I'll take the MAKEINTRESOURCE macro to resolve this problem.

Eric

"Heinz Ozwirk" <ho**********@arcor.de> wrote in message
news:42***********************@newsread2.arcor-online.net...
"Eric" <ba********@kull.ch.nospam.me.com> schrieb im Newsbeitrag
news:db**********@news.hispeed.ch...
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

Jul 23 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.