Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macro vs Function in C

I often see instances in which using a macro is better than using a function.

Could someone explain me with an example the disadvantage of a macro compared to a function?

like image 414
Kyrol Avatar asked Feb 01 '12 22:02

Kyrol


People also ask

Why use a macro instead of a function?

Speed versus size The main benefit of using macros is faster execution time. During preprocessing, a macro is expanded (replaced by its definition) inline each time it is used. A function definition occurs only once regardless of how many times it is called.

What is function-like macro in C?

Function-like macro definition: An identifier followed by a parameter list in parentheses and the replacement tokens. The parameters are imbedded in the replacement code. White space cannot separate the identifier (which is the name of the macro) and the left parenthesis of the parameter list.

What is a macro in C programming?

A macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro. There are two kinds of macros. They differ mostly in what they look like when they are used.


2 Answers

Macros are error-prone because they rely on textual substitution and do not perform type-checking. For example, this macro:

#define square(a) a * a 

works fine when used with an integer:

square(5) --> 5 * 5 --> 25 

but does very strange things when used with expressions:

square(1 + 2) --> 1 + 2 * 1 + 2 --> 1 + 2 + 2 --> 5 square(x++) --> x++ * x++ --> increments x twice 

Putting parentheses around arguments helps but doesn't completely eliminate these problems.

When macros contain multiple statements, you can get in trouble with control-flow constructs:

#define swap(x, y) t = x; x = y; y = t;  if (x < y) swap(x, y); --> if (x < y) t = x; x = y; y = t; --> if (x < y) { t = x; } x = y; y = t; 

The usual strategy for fixing this is to put the statements inside a "do { ... } while (0)" loop.

If you have two structures that happen to contain a field with the same name but different semantics, the same macro might work on both, with strange results:

struct shirt  {     int numButtons; };  struct webpage  {     int numButtons; };  #define num_button_holes(shirt)  ((shirt).numButtons * 4)  struct webpage page; page.numButtons = 2; num_button_holes(page) -> 8 

Finally, macros can be difficult to debug, producing weird syntax errors or runtime errors that you have to expand to understand (e.g. with gcc -E), because debuggers cannot step through macros, as in this example:

#define print(x, y)  printf(x y)  /* accidentally forgot comma */ print("foo %s", "bar") /* prints "foo %sbar" */ 

Inline functions and constants help to avoid many of these problems with macros, but aren't always applicable. Where macros are deliberately used to specify polymorphic behavior, unintentional polymorphism may be difficult to avoid. C++ has a number of features such as templates to help create complex polymorphic constructs in a typesafe way without the use of macros; see Stroustrup's The C++ Programming Language for details.

like image 157
Chiara Coetzee Avatar answered Nov 15 '22 23:11

Chiara Coetzee


Macro features:

  • Macro is Preprocessed
  • No Type Checking
  • Code Length Increases
  • Use of macro can lead to side effect
  • Speed of Execution is Faster
  • Before Compilation macro name is replaced by macro value
  • Useful where small code appears many time
  • Macro does not Check Compile Errors

Function features:

  • Function is Compiled
  • Type Checking is Done
  • Code Length remains Same
  • No side Effect
  • Speed of Execution is Slower
  • During function call, Transfer of Control takes place
  • Useful where large code appears many time
  • Function Checks Compile Errors
like image 39
zangw Avatar answered Nov 15 '22 23:11

zangw