1. ## Macros return values

How does one code a macro to return a value?

I need to create two macros max1(x,y) max2(x,y,z)

Need to find the max value of given arguments.

So I was going to use the conditional operator. I put () around everything since I want the macro to return a value.

Code:
```#ifndef _max_
#define int MAX2 = ((x > y) ? (x) : (y));
#define int MAX3 = (((MAX2) > (z)) ? (MAX2) : (z));
#endif```
Any help would be appreciated.
Thanks
SJ

2. Holy COW! I figured it out.

Did not need the assignment(=) expression(?) am I using the terms right?
Removed those and some of the individual () around the variables. Now it works great.

Code:
```#ifndef _max_
#define MAX2 ((x > y) ? x : y)
#define MAX3 ((MAX2 > z) ? MAX2 : z)
#endif```
Code:
```void main()
{
int x = 10;
int y = 20;
int z = 25;

printf("Max value of MAX2 is: %d\n", MAX2);
printf("Max value of MAX3 is: %d\n", MAX3);

}```

3. It's still not how such a macro is meant to be written.
You should be able to use it like MAX2(5, 7) or with variables of other names.
For this you need parameters to the macro.
A quick search and you will find the answer.

4. iMalc

But the assignment states that the macros must return the max value of the give arguments MAX2(x,y) and MAX3(x,y,z). Let macro MAX3 use the macro MAX2.

How else should I do it? If I put values in the macros I cannot find the max value of the arguments.

Thanks
SJ

5. There are several reasons to use macros, the major one is to create a function template which can be applied to different types of arguments, typically the whole range of integers and floats.
This is the case for your MAX macros.
I suggest you first write the C function (without macro) to compute the max of two ints
Code:
`int max(int x, int y) { ... }`
Once it's done, remove the types and adjust the syntax to make it a macro.

What iMalc was saying is that x and y are just formal parameters.
With the macros MAX, i expect to be able to do:
Code:
```int main(void) {
float i = 3.14;
float j = 5;
float m = MAX(i, j);
...
}```
You can see it doesn't work with your version.

6. The problem is that you've hard-coded the variable names into your macros, which makes them useless with different variable names or constants.

Look at your assignment (as you've stated it) :
I need to create two macros max1(x,y) max2(x,y,z)
Your version doesn't have parameters for the macros, so it doesn't conform to the assignment.

And the parentheses around the parameters in a macro are important for controlling precedence.

7. Using macros is always avoidable and not usually recommended unless you are programming something where there is a restriction of memory or time (embedded systems).

That being said, you can use these - With extreme caution
Code:
```#include <stdio.h>
#include <stdlib.h>

#define MIN(x,y) (y ^ ((x ^ y) & -(x < y)))
#define MAX(x,y) (x ^ ((x ^ y) & -(x < y)))

int main(void)
{

int i=100;
int j=500;
int k,l;

k = MIN(i,j);
l = MAX(i,j);
printf("\nMin = %d, Max = %d",k,l);

return EXIT_SUCCESS;

}```

8. Originally Posted by Click_here
Using macros is always avoidable and not usually recommended unless you are programming something where there is a restriction of memory or time (embedded systems).
You mean using "function-like" macros is avoidable. Using macros for constants isn't (e.g., EXIT_SUCCESS, although I don't use that one myself).

That being said, you can use these - With extreme caution
I'm sorry, but those macros are ridiculous! (I'm assuming they're a joke.) Consider:
Code:
`#define MIN(x,y) (y ^ ((x ^ y) & -(x < y)))`
It performs 5 operations to determine the min, when 1 is enough (or is it 2?) :
Code:
`#define MIN(x,y) ((x) < (y) ? (x) : (y))`
Also, you forgot to put the (absolutely necessary) parentheses around your parameters in the macro definition.

9. You mean using "function-like" macros is avoidable
Whoops - Yes I did

The macro I suggested is a good one in systems that are expensive to do a branch/jump - It was cut and paste from some code I had.

You were right in saying that it takes longer to do (certainly on my processor) -

It performs 5 operations to determine the min, when 1 is enough (or is it 2?)
Code:
```k = (i<j) ? i : j;
00401321    call   0x401740 <__main>
00401326    movb   \$0xfa,0xc(%esp)
0040132B    movb   \$0x64,0xd(%esp)
00401330    mov    0xc(%esp),%dl
00401334    mov    0xd(%esp),%al
00401338    cmp    %dl,%al
0040133A    jle    0x40133e <main+38>
0040133C    mov    %dl,%al
0040133E    mov    %al,0xe(%esp)
00401342    mov    \$0x0,%eax

k = (y ^ ((x ^ y) & -(x < y)));
00401321    call   0x401750 <__main>
00401326    movb   \$0xfa,0xc(%esp)
0040132B    movb   \$0x64,0xd(%esp)
00401330    mov    0xd(%esp),%al
00401334    mov    0xc(%esp),%dl
00401338    xor    %eax,%edx
0040133A    mov    0xc(%esp),%al
0040133E    cmp    0xd(%esp),%al
00401342    setl   %al
00401345    neg    %eax
00401347    and    %edx,%eax
00401349    xor    0xd(%esp),%al
0040134D    mov    %al,0xe(%esp)
00401351    mov    \$0x0,%eax```
The ? operator was much more efficient (with 6 lines of assembly as compared to 10 lines of assembly)

Also, you forgot to put the (absolutely necessary) parentheses around your parameters in the macro definition.
Whoops again - Thank-you for pointing that out

10. Originally Posted by Click_here
The ? operator was much more efficient (with 6 lines of assembly as compared to 10 lines of assembly)
Only if you're talking about code size. If you're interested in speed, the only real way to know is to run and time each example.

11. So you folks have me confused now.

I have my macros in a header file. I have a function under main in another files. I hard coded my variables in main, but left the macros as a function using conditional op. What is the problem here?

Once it's done, remove the types and adjust the syntax to make it a macro.

What iMalc was saying is that x and y are just formal parameters.
With the macros MAX, i expect to be able to do:
Are you saying this because I used integer types? I dont know what the difference is really between what I did and this? Here the type is different but only in main? What else is the difference?

Code:
```int main(void) {
float i = 3.14;  float j = 5;  float m = MAX(i, j);  ... }```

Thanks
SJ

12. I am a little confused by your confusion

Do you understand why it was recommended that you write a function-style macro instead of the macro that you wrote?

13. No I do not understand why it was recommended. Please explain.

14. Originally Posted by sjmp
No I do not understand why it was recommended. Please explain.
Ah. The gist of this has already been stated in posts #3, #5 and #6. If I were to add my own explanation...

Think back on the advantage of a function: you can call it with different arguments, execute the same operation, and obtain a result. Same function, different input, it works.

The same applies for a function-style macro: you supply the macro with different arguments, and then you get the same macro replacement (the "return" of a value). If you did not use a function-style macro, then you cannot supply arguments. It is as if you are using global variables, and you're stuck with particular names.

For example, suppose that max0 is a function-style macro:
Code:
```int x = 1;
int y = 2;
int z = 3;
int a = max0(x, y);
int b = max0(y, z);```
With your MAX2 macro, we cannot do this: there is no way to get the max of y and z without writing more code that does the same operation of finding the max of two values... at least not without changing the values of x and y.

15. So my macro functions max2, max3

should not be the conditional ops that solve the problem? I have to initialize the variables in the function main. I have to use MAX2 to solve for MAX3.

everything i did works. but clearly I am missing the entire point of this exercise.