Macros are often used instead of functions in languages like C or C++ for performance gains and flexibility in specific scenarios. They avoid function call overhead but come with trade-offs like no type safety.

Performance Edge

Macros expand at preprocess time, embedding code directly—no stack pushes, jumps, or returns needed. This makes them faster for tiny operations repeated often, like in Linux kernel code where every cycle counts. Functions, even inlined, carry minor runtime costs from compilation and potential non-inlining by optimizers.

Imagine debugging a hot loop in an embedded system: a macro like #define MAX(a,b) ((a)>(b)?(a):(b)) duplicates inline, dodging call overhead entirely, while a function might still bloat the stack in edge cases.

Type Flexibility

Macros ignore types, acting as generic templates before compilation. Need a min/max for ints, floats, or structs? One macro handles all without templates or overloads—perfect for pre-C++11 or kernel devs avoiding bloat.

  • No prototypes required : Just #define, and it works across files.
  • Multi-statement blocks : Wrap in do { ... } while(0) for clean use in if-statements.

Functions demand prototypes, type checks, and separate compilation, slowing generic use.

Drawbacks Highlighted

Macros lack type checking, risking silent bugs—like side effects from arguments evaluated multiple times (MAX(x++, y) increments x twice). No debug symbols either; expanded code muddies stack traces. Modern compilers inline functions reliably, often making macros obsolete except for kernel or low-level tricks.

"Macros are substituted directly... use more memory space than a respective function. On the other hand, a function requires more time."

When to Choose Macros

  • Kernel/real-time : Speed trumps safety; Linux favors them for assertions or adapters.
  • Constants : #define PI 3.14 wastes no RAM vs. const vars.
  • Avoid for complex logic : Use inline functions for readability and safety.

Aspect| Macro| Function
---|---|---
Speed| Faster (no call) 1| Slower overhead 1
Type Safety| None 1| Full checks 4
Debugging| Poor (expanded) 1| Symbols intact 3
Generics| Native 5| Needs templates/inline 9
Size| Code duplicates 1| Shared binary 1

TL;DR : Macros shine for micro-optimizations and generics in performance- critical code like kernels, but functions win for safety everywhere else.

Information gathered from public forums or data available on the internet and portrayed here.