C
Beginner
1 min read
Function-Like Macros and Pitfalls
Example
#include <stdio.h>
/* Correct: all params and result parenthesised */
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define ABS(x) (((x) < 0) ? -(x) : (x))
#define CLAMP(v, lo, hi) (MAX((lo), MIN((v), (hi))))
/* Multi-statement macro using do-while(0) */
#define SWAP(type, a, b) do { \
type _tmp = (a); \
(a) = (b); \
(b) = _tmp; \
} while (0)
/* Stringification with # operator */
#define STRINGIFY(x) #x
#define TO_STRING(x) STRINGIFY(x)
/* Token pasting with ## operator */
#define MAKE_VAR(prefix, num) prefix##num
int main(void)
{
printf("MAX(3,7) = %d\n", MAX(3, 7)); /* 7 */
printf("MIN(3,7) = %d\n", MIN(3, 7)); /* 3 */
printf("ABS(-5) = %d\n", ABS(-5)); /* 5 */
printf("CLAMP(15,0,10)= %d\n", CLAMP(15,0,10)); /* 10 */
int x = 10, y = 20;
SWAP(int, x, y);
printf("After SWAP: x=%d y=%d\n", x, y); /* 20, 10 */
/* Double-evaluation danger (illustrative — avoid in real code) */
int i = 3;
/* MAX(i++, 5) would increment i TWICE — undefined behaviour */
/* Use a temporary variable instead: */
int safe = i;
printf("safe MAX: %d\n", MAX(safe, 5));
printf("STRINGIFY: %s\n", STRINGIFY(Hello World));
printf("Line: " TO_STRING(__LINE__) "\n");
int MAKE_VAR(data, 42) = 999;
printf("data42 = %d\n", data42);
return 0;
}