0

I want to change the priority of the preprocessor define process.

see the following code:

#include <iostream> #include <sstream> #define $(x) << x << #define f(x) (#x) int main() { auto world = "universe!"; std::stringstream ss; ss << f(Hello $(world)) << std::endl; std::cout << ss.str(); return 0; } 

The code run, but the 'f' macro will always processed before the '$' macro.

The current output:

Hello $(world) 

Expected output:

Hello universe! 

Thx.

8
  • 1
    is there a "real-world" use case for that or is this only out of interest? Commented Jan 17, 2023 at 9:17
  • 1
    it's more interest, otherwise I could use the world var directly in the stringstream. Commented Jan 17, 2023 at 9:22
  • I would advise to stop looking into the preprocessor too much. What do you want to achieve isn't it something that can be done using template functions? Using the preprocessor is not the first thing I would try in C++ . Commented Jan 17, 2023 at 9:26
  • 1
    Does this answer your question? How, exactly, does the double-stringize trick work? Commented Jan 17, 2023 at 9:30
  • 5
    'f' macro will always processed before the '$' macro. I do not understand, if that wouldn't be the case, the output would be "Hello << world <<". f is (#x) means everything is going to be #x, there is no place where << would be removed. The expansion would be f(Hello $(world)) -> f(Hello << world <<) -> "Hello << world <<". Commented Jan 17, 2023 at 9:34

2 Answers 2

2

"Solving" the problem:

#include <iostream> #include <sstream> #define $(x) << " " << x #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define f(x, y) TOSTRING(x) y int main() { auto world = "universe!"; std::stringstream ss; ss << f(Hello, $(world)) << std::endl; std::cout << ss.str(); return 0; } 

Output:

Hello universe! 
Sign up to request clarification or add additional context in comments.

2 Comments

you don't change the priority of the preprocessor processing, you use parameters.
@code_by_cr yes I know, that is why I quoted it as "solving". Maybe a comment with a link would be more appropriate
1

You might "delay" expansion with extra indirection:

#define $(x) << x << #define STRINGIFY(x) #x #define f(x) STRINGIFY(x) 

but you won't get your expected result but Hello << world << Demo

Without changing your MACRO, you might already get your result by "fixing" your parenthesis (and surrounding):

ss << f(Hello) " " $(world) /*<<*/ std::endl; 

Demo.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.