#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    132
    Rep Power
    2

    Question about macro functions


    Hi guys.

    why is this legal:

    Code:
    #define BIGGER(x,y) (x>y?x:y);
    
    int main()
    {
    	int num1, num2;
    	int biggerNum;
    
    	printf("Enter two numbers:");
    	scanf("%d %d", &num1, &num2);
    
    	biggerNum=BIGGER(num1, num2)
    	printf("bigger number is: %d", biggerNum);
    }
    but this is unacceptable by the compiler:
    Code:
    #define BIGGER(x,y) (x>y?x:y);
    
    int main()
    {
    	int num1, num2;
    	int biggerNum;
    
    	printf("Enter two numbers:");
    	scanf("%d %d", &num1, &num2);
    
    	printf("bigger number is: %d", BIGGER(num1, num2));
    }
    expected ) before ; token

    thanks in advanced!
    Last edited by so.very.tired; January 28th, 2013 at 11:46 AM.
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,162
    Rep Power
    2222
    Basically, all that a macro does is replace the macro name with the macro itself. That is refered to as "macro expansion". Part of the task of the pre-processor is to perform macro expansion. It quite literally creates a new source file.

    Here is what the first example produces:
    Code:
    	biggerNum=(num1>num2?num1:num2);
    As you can see, that is valid C syntax.

    Now here is what the second example produces:
    Code:
    printf("bigger number is: %d", (num1>num2?num1:num2););
    As you can see, that is not valid C syntax.

    Now, if you were to remove the semicolon from the macro and add a semicolon to the first example, both should work.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    132
    Rep Power
    2
    thank you, dwise1_aol.
  6. #4
  7. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,110
    Rep Power
    1803
    Firstly a macro is a macro and a function is a function. There is no such thing as a "macro function". You might however refer to a "function-like macro" to distinguish a simple constant identifier from a macro that takes parameters.

    Use of function-like macros is usually ill-advised and most are badly defined. For example your example should at least be defined thus:

    Code:
    #define BIGGER(x,y) ((x)>(y)?(x):(y))
    because the parameters x and y themselves may be expressions involving other operators and without the parentheses, the order of evaluation might be unexpected.

    Another problem with this macro is that both x and y are evaluated twice, which for simple variables or literal constants may not be a problem, but for complex expressions is wasteful, and for expressions with side effects could produce very strange results.

    There are two reasons usually cited for using a macro

    1. Performance (avoiding a function call overhead).
    2. Generic functions that work for any parameter type.


    The first aim is often defeated for the reasons mentioned above, and in any case any decent compiler will automatically in-line suitably short functions.

    The second is a good way of shooting yourself in the foot - type agreement and checking cannot be enforced and it is a good thing not something to be defeated.

    Another reason to avoid macros is that they are invisible to the symbolic debugger. You cannot step-into a macro as you can a function and you cannot observe its variable state or place break-points within it. A simple macro such as this may be acceptable, but it really does not gain you much while causing potential problems.

    In C++ most of the uses for macros (function-like and simple) in C are replaced by more flexible and powerful language mechanisms such as function overloading, in-lining, different const semantics, template functions and polymorphism. While you should be wary of writing a macro in C, you should hear alarm bells in C++. This is by the is an argument for using C++ rather than avoiding it.

    But you may say "I'm not using C++" but you are. You have declared main() to return an int, but have not explicitly returned a value. That is only valid in C++ (and then only in main), a C compiler should reject that.
    Last edited by clifford; January 28th, 2013 at 01:50 PM.
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,162
    Rep Power
    2222
    I would add that in about 22 years of programming in C and C++ professionally, I have never written a function-like macro nor have I seen any of my colleagues write one. However, we do use macros extensively to centralize the definition of constant values and to control conditional compilation (we work mainly in C).

    I have seen macros used extensively in assembly programming, including function-like macros, which is probably where C got them from.

IMN logo majestic logo threadwatch logo seochat tools logo