简体   繁体   中英

What are the benefits of using macros instead of functions in C?

First Code:

#include <stdio.h>
 
int area(int a,int b){
        int area1 = a*b;
        return area1;
    }
int main()
{
    
    int l1 = 10, l2 = 5, area2;
 
    area2 = area(l1,l2);
 
    printf("Area of rectangle is: %d", area2);
 
    return 0;
}

Second Code:

#include <stdio.h>
 
// macro with parameter
#define AREA(l, b) (l * b)

int main()
{
    int l1 = 10, l2 = 5, area;
 
    area = AREA(l1, l2);
 
    printf("Area of rectangle is: %d", area);
 
    return 0;
}

Same output to both codes: Area of rectangle is: 50

My Question: So obviously, macros in C language are the same as functions, but macros take less space (fewer lines) than functions. Is this the only benefit of using macros instead of functions? Because they look roughly the same.

Macros are most definitely not the same as functions. Macros are text substitutions 1 ; they are not called like functions.

The problem with your AREA macro is that it won't behave well if you pass an expression like AREA(l1+x,l2) - that will expand to (l1+x * l2) , which won't do what you want. Arguments to macros are not evaluated, they are expanded in place.

Macros and function-like macros are useful for creating symbolic constants, simplifying repeated blocks of text, and for implementing crude template-like behavior.


  1. Strictly speaking they are token substitutions, but the principle is the same.

A case where macros are useful is when you combine them with __FILE__ and __LINE__ .

I have a concrete example in the Bismon software project. In its file cmacros_BM.h I define

// only used by FATAL_BM macro
extern void fatal_stop_at_BM (const char *, int) __attribute__((noreturn));
#define FATAL_AT_BIS_BM(Fil,Lin,Fmt,...) do {                   \
    fprintf(stderr, "BM FATAL:%s:%d: <%s>\n " Fmt "\n\n",       \
            Fil, Lin, __func__, ##__VA_ARGS__);                 \
    fatal_stop_at_BM(Fil,Lin); } while(0)

#define FATAL_AT_BM(Fil,Lin,Fmt,...) FATAL_AT_BIS_BM(Fil,Lin,Fmt,##__VA_ARGS__)

#define FATAL_BM(Fmt,...) FATAL_AT_BM(__FILE__,__LINE__,Fmt,##__VA_ARGS__)

and fatal errors are calling something like (example from file user_BM.c )

  FILE *fil = fopen (contributors_filepath_BM, "r+");
  if (!fil)
    FATAL_BM ("find_contributor_BM cannot open contributors file %s  : %m",
              contributors_filepath_BM);

When that fopen fails, the fatal error message shows the source file and line number of that FATAL_BM macro invocation.

The fatal_stop_at_BM function is defined in file main_BM.c

Notice also that some of your C files could be generated by programs like GNU bison , GNU m4 , ANTLR , SWIG and that preprocessor symbols are also used by GNU autoconf .

Study also the source code of the Linux kernel . It uses macros extensively.

Most importantly, read the documentation of your C compiler (eg GCC ). Many C compilers can show you the preprocessed form of your C code.


Your

 // macro with parameter
 #define AREA(l, b) (l * b)

is wrong and should be #define AREA(l, b) ((l) * (b)) if you want AREA(x+2,y-3) to work as expected.

For performance reasons, you could have defined your function as

inline int area(int a,int b){ return a*b; }

See also:

I agree with @Eric Postpischil. Macros are not supported by old compilers and they don't know anything about macros. So, this makes debugging harder if you use an old compiler.

Is this the only benefit of using macros instead of functions?

No, macros are function-like and can be used to define only very simple things such as simple formulas but it's not recommended to define a C function with them because they try to put everything linear and flat and that's why you may face software design issues and they make debugging harder. So, this is not always a benefit.

And in your case, I think it's not a big and serious problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM