Thread: Macros return values

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    55

    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. #2
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    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. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    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.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    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. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    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.
    Last edited by root4; 08-15-2012 at 03:11 PM.

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    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.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  7. #7
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    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. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by Click_here View Post
    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.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  9. #9
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    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. #10
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    Quote Originally Posted by Click_here View Post
    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. #11
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    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. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    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?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    No I do not understand why it was recommended. Please explain.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote 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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to use return values
    By Furious5k in forum C++ Programming
    Replies: 3
    Last Post: 02-05-2009, 09:07 PM
  2. Return values
    By pritin in forum C++ Programming
    Replies: 9
    Last Post: 03-26-2007, 05:24 PM
  3. I'll try again: C++ DLL return values for VB
    By WebSnozz in forum C++ Programming
    Replies: 6
    Last Post: 01-20-2003, 01:12 AM
  4. Return values
    By Juganoo in forum C Programming
    Replies: 2
    Last Post: 01-03-2003, 09:28 PM
  5. Return Values ( C )
    By Inept Pig in forum C Programming
    Replies: 2
    Last Post: 04-16-2002, 10:02 AM

Tags for this Thread