How does preprocessor replacement works?

I have defined this macro:
#define draw_rect(x, y, w) r = {x, y, w, 1};SDL_RenderFillRect(window->getRenderer(), &r);std::cout<<(x+w)<<" "<<y<<"\n"
And I use it like this:
1
2
3
if(y!=0){
  draw_rect(xc-x, yc+y-1, width);
}

In the IF above, do I really need to use brackets? Or does the compiler adds its own when replacing macros?
Last edited on
Let's apply it and actually see what happens.

sourcefile.cpp
1
2
3
4
5
#define draw_rect(x, y, w) r = {x, y, w, 1};SDL_RenderFillRect(window->getRenderer(), &r);std::cout<<(x+w)<<" "<<y<<"\n"
 
if(y!=0){
  draw_rect(xc-x, yc+y-1, width);
}


Instruct compiler to apply preProcessor and output results:
g++ -E sourceFile.cpp

Results:
1
2
3
4
5
6
7
8
9
10
11
# 1 "sourceFile.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "sourceFile.cpp"


if(y!=0){
  r = {xc-x, yc+y-1, width, 1};SDL_RenderFillRect(window->getRenderer(), &r);std::cout<<(xc-x+width)<<" "<<yc+y-1<<"\n";
}


You can see exactly what the preprocessor did.



@Moschops So no brackets added, thank you!
1. A function-like macro should behave like a function so you should wrap the whole thing in a do { ... } while(0); Then you don't need the braces in the IF.

2. Even then, if parameters are used more than once (like x and w) and they have side-effects in the call then they will happen more than once. eg: draw_rect(xc++, yc++, width); will increment xc twice.

3. The macros depends on r being earlier declared.

4. An in-line function avoids all these problems and should produce code that is at least as efficient. Ie: this sort of macro is (and has been for 20 years) frowned upon in C and just stupid in C++.
Topic archived. No new replies allowed.