6

I am trying to understand the idea of function like Macros however there are a few points that befuddle me. For example say we have:

#define Max(a,b)  ((a)>(b)) ? (a):(b))

and I call it like such

int i = Max(4,5);

This will evaluate a conditional expression equivalent to a>b? If yes then a, else b. But I'm confused as to how the Max function knows what to do with the arguments. Unlike an actual function, the implementation isn't written in code in the calling program. is the statement to the right of the define statement doing this for me? Its just a new thing for me and I want to make sure I understand what is happening here.

This particular part of function like macros confuses me. I know that these types of macros are useful for reducing overhead costs since they exclude the JSR RTS processor instructions which saves memory on the stack.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
PresidentRFresh
  • 93
  • 1
  • 2
  • 10

4 Answers4

13
#define Max(a,b)  ((a)>(b)) ? (a):(b))

is a macro, that causes nothing else but a simple textual replacement within your code, which means that during the preprocessing this line:

int i = Max(4,5);

is changed into:

int i = ((4)>(5)) ? (4):(5));

Note that there is no type safety while working with macros like this one and you will have really hard time while debugging your code as well. Good rule of thumb is: Don't use macro when you can achieve the same with function:

int max(int a, int b) {
    return (a > b) ? a : b;
}
Guilherme Bernal
  • 8,183
  • 25
  • 43
LihO
  • 41,190
  • 11
  • 99
  • 167
  • Ah so by type safety you mean that I could theoretically pass an int, char, etc and it would still be valid? – PresidentRFresh Mar 22 '13 at 16:47
  • 7
    I actually think this particular example involving `max()` is a great time to use a macro instead of a function. In C, where there are no templates or generics, you'd have to write a separate `max()` function for each type, whereas with a simple macro it all Just Works (for types where `>` is meaningful). – Graham Borland Mar 22 '13 at 16:50
  • 1
    @PresidentRFresh: Anything can be "passed" to this macro. The problem is that sometimes it might lead to buggy behavior (macros being used in a way they were not meant to be used). For example someone could pass pointers to it which would be compile-able but producing bad results. – LihO Mar 22 '13 at 16:51
  • @GrahamBorland: I agree that macros can be sometimes handy, but still there is a risk, that a programmer using them will make some mistake (could be just a silly typo) and this kind of error will be quite hard to find. – LihO Mar 22 '13 at 16:58
  • You could use the `inline` keyword to make it more like a macro, but with type safety. – kazmer Mar 02 '19 at 22:09
6

Just stop thinking about macro like compilable code. Macros are "resolved" by pre-processor, not actually during compilation stage. So by macro definitions you just define how to process certain string in text file. Only output of pre-processor is passed to compiler. You can use gcc -E to see your source after pre-processor. It is still C code on this stage but without any preprocessor directive.

Hope this will help you.

Roman Nikitchenko
  • 12,800
  • 7
  • 74
  • 110
5

What the compiler actually sees, after preprocessing, is:

int i = ((4)>(5)) ? (4):(5));

The parameters passed to the macro are substituted into the body of the macro.

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
4

try to build your code with the gcc -E and see how your code look before compiling it

In fact in the build process the compilator transform your actual code to a preprocessor code. In the preprocessor phase the compilator replace all macro in your c code with its content and generate another code called preprocessor code and then the compilateor generate the object code from the preprocessor code

The gcc -E allow you to see your preprocessor code

MOHAMED
  • 41,599
  • 58
  • 163
  • 268
  • Oh I see. I am aware that this is not an actual function but I was confused as to how it operated. Thank you for clearing that up. – PresidentRFresh Mar 22 '13 at 16:44