-2

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.

user134613
  • 109
  • 4
  • 1
    It's usually best to use an inline function instead of a macro. Leave macros for other token pasting. Check this question https://stackoverflow.com/questions/1640344/when-should-you-use-macros-instead-of-inline-functions –  Feb 06 '21 at 19:21
  • 5
    Try `AREA( x + y, a + b )` as both a macro and a function... – Andrew Henle Feb 06 '21 at 19:25
  • 4
    Re "*other than space efficiency*", Since they are "inlined" each time they are used, using macro can take up *more* space. – ikegami Feb 06 '21 at 19:30
  • They avoid a function call. The result can be subject to constant folding. They can be used where a constant is required (depending on the macro). They can affect code generation. – ikegami Feb 06 '21 at 19:32
  • Function-like macros are not equivalent to functions, and don't always take less space than functions. – M. Nejat Aydin Feb 06 '21 at 19:33
  • 3
    _"obviously, macros in C language are the same as functions"_ - that is not "obvious" because it is not true. Taking _"fewer lines"_ is not an advantage. That;s just typing., and is not necessarily true in any case. `int area(int a,int b){return a * b;}` - one line and no unnecessary variable, type-safe, and likely to be in-lined with even the most modest optimiser. Your `AREA` macro is seriously flawed in any case and one example of why function-like macros should be avoided `#define AREA(l, b) ((l) * (b))`. – Clifford Feb 06 '21 at 19:40
  • If you were to ask _"What are the **disadvantages** of using macros...?"_ you'd more likely get an answer, but surely there is a duplicate on SO? – Clifford Feb 06 '21 at 19:43
  • 1
    Function calls used to be more expensive, and old compilers did not optimize them, so macros would be more efficient. And, of course, there are situations were macros do things functions do not, such as refer to identifiers in the surrounding scope. But, in modern C, static inline functions should often be preferred to macros. – Eric Postpischil Feb 06 '21 at 19:47
  • 1
    If you are being paid by the quarter-hour, or on a cost-plus contract, using macros freely can boost your income considerably by expanding the test/debug development phases. It can also make you difficult to fire because your code is almost indecipherable. – Martin James Feb 06 '21 at 23:19
  • Notice that C code can be *generated*, and you could use C code generators like [GNU bison](https://www.gnu.org/software/bison/), [SWIG](http://swig.org/), [GPP](https://logological.org/gpp), [Bigloo](http://www-sop.inria.fr/members/Manuel.Serrano/bigloo/) etc... In some cases, you should write your own C code generator, and be more productive than with the C preprocessor. – Basile Starynkevitch Feb 07 '21 at 07:13
  • @AndrewHenle What do u mean with x,y,a,and b? what do they represent? So AREA( x+y, a+b ) takes two parameters, the 1st one is the sum of x and y and the 2nd is the sum of a and b, but what does it do with the parameters? – user134613 Feb 08 '21 at 18:15
  • @user134613 Given the macro `#define AREA(l, b) (l * b)`, what do you think happens when you write `AREA( x+y, a+b )` to compute the area of a rectangle? – Andrew Henle Feb 08 '21 at 20:31

3 Answers3

3

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 (e.g. 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:

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
2

Macros are most definitely not the same as functions. Macros are text substitutions1; 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.
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • By using parentheses around arguments in the macro definition the issue you show of evaluation vs. expansion can be avoided. Still, it's usually not a good idea to use macros instead of functions, except for the reasons you mention. – Jan Christoph Terasa Feb 07 '21 at 07:34
1

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.

  • 1
    Macros are supported by all C compilers conforming to C89 or later, and they were supported by many earlier ones, either directly or via a separate C preprocessor. There is no plausible reason to fear that a C compiler you use today will fail to support macros. Additionally, your prose could be read as asserting that Eric claimed otherwise, but I am confident that he did not, not even in any comments that might since have been deleted. – John Bollinger Feb 07 '21 at 15:29