Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. C Language Dictionary
  3. Function Macros (#define)

Function Macros (#define)

A macro that takes arguments. It can be used like a function, but the preprocessor performs simple text substitution before compilation. Because it is expanded inline, there is no function call overhead, and you can write generic code that is independent of types.

Syntax

// A constant macro with no arguments.
#define CONSTANT_NAME value

// A function-like macro with arguments (wrap each argument and the whole expression in parentheses).
#define MACRO_NAME(arg1, arg2) ((arg1) operator (arg2))

// A multi-line macro continues each line with a backslash.
#define MACRO_NAME(x) \
    do { \
        statement; \
    } while (0)

// The stringizing operator (#). Converts an argument into a string literal.
#define STRINGIFY(x) #x

// The token-pasting operator (##). Concatenates two tokens into one.
#define CONCAT(a, b) a##b

Function-like Macro Notation and Notes

Notation / OperatorDescription
Wrap arguments in parenthesesAs in #define SQUARE(x) ((x) * (x)), wrap each argument in parentheses. This prevents incorrect behavior caused by operator precedence during expansion.
Wrap the whole expression in parenthesesWrapping the entire macro expansion in parentheses prevents unintended grouping when the macro is embedded in an expression.
do { } while (0)An idiom for safely writing multi-statement macros. It works correctly even when used as the body of an if statement.
# (stringizing)Converts a macro argument into a string literal enclosed in double quotes.
## (token-pasting)Concatenates two tokens into a single identifier.

Sample Code

#include <stdio.h>

// Common examples of function-like macros.
#define MAX(a, b)    ((a) > (b) ? (a) : (b))
#define MIN(a, b)    ((a) < (b) ? (a) : (b))
#define SQUARE(x)    ((x) * (x))
#define ABS(x)       ((x) >= 0 ? (x) : -(x))

// A macro for debugging (stringizes the variable name with #).
#define PRINT_INT(x) printf(#x " = %d\n", (x))

// A multi-statement macro using do-while(0).
#define SWAP(type, a, b) \
    do { \
        type _tmp = (a); \
        (a) = (b); \
        (b) = _tmp; \
    } while (0)

// Generates an identifier dynamically using token-pasting.
#define MAKE_VAR(name, num) name##num

int main(void) {
    int x = 5, y = 3;

    printf("MAX(%d, %d) = %d\n", x, y, MAX(x, y));    // Prints "MAX(5, 3) = 5".
    printf("MIN(%d, %d) = %d\n", x, y, MIN(x, y));    // Prints "MIN(5, 3) = 3".
    printf("SQUARE(%d) = %d\n", x, SQUARE(x));        // Prints "SQUARE(5) = 25".
    printf("ABS(-7) = %d\n", ABS(-7));                // Prints "ABS(-7) = 7".

    // Debug output using the # operator.
    int score = 98;
    PRINT_INT(score); // Prints "score = 98".

    // Swap values using the SWAP macro.
    printf("Before swap: x=%d, y=%d\n", x, y);
    SWAP(int, x, y);
    printf("After swap: x=%d, y=%d\n", x, y); // Prints "x=3, y=5".

    // Example of the ## operator.
    int MAKE_VAR(val, 1) = 100; // Expands to: val1 = 100.
    printf("val1 = %d\n", MAKE_VAR(val, 1)); // Prints "val1 = 100".

    // Passing an expression with side effects to a macro causes unintended behavior.
    // int a = 3;
    // printf("%d\n", SQUARE(a++)); // Dangerous: a is incremented twice.

    return 0;
}

Notes

Because function-like macros are text substitutions performed by the preprocessor, passing an expression with side effects (such as an increment) as an argument causes unintended behavior. SQUARE(a++) expands to ((a++) * (a++)), causing the increment to happen twice. From C99 onward, consider using inline functions or the type-generic _Generic facility for the same purpose.

Not wrapping arguments in parentheses leads to operator precedence issues. For example, with #define DOUBLE(x) x * 2, DOUBLE(1 + 2) expands to 1 + 2 * 2 = 5. Always wrap arguments in parentheses.

For constant macros, see #include / #define (Constants). For conditional compilation, see #ifdef / #ifndef.

If you find any errors or copyright issues, please .