Skip to content

FAQ: C macro that prints the function name, parameter names with values

Ulrond edited this page Aug 8, 2024 · 2 revisions

C macro that prints the function name, parameter names, and their corresponding values for debugging purposes.

It uses the __func__ identifier to get the function name and variadic macros to handle a variable number of parameters.

#include <stdio.h>

#define LOG_PARAMS(...) \
    do { \
        printf("%s(", __func__); \
        _log_params_helper(__VA_ARGS__); \
        printf(")\n"); \
    } while (0)

#define _log_params_helper(param, ...) \
    do { \
        printf(#param " = %p", (void*)param); \
        if (sizeof((int[]){__VA_ARGS__})/sizeof(int) > 0) { \
            printf(", "); \
            _log_params_helper(__VA_ARGS__); \
        } \
    } while (0)

Explanation:

  • LOG_PARAMS: This is the main macro that you'll use in your functions.
    • It uses __func__ to print the function name.
    • It calls _log_params_helper to handle the actual parameter logging.
  • _log_params_helper: This is a recursive helper macro.
    • It takes a parameter name and its value, prints them in the format param = value.
    • It uses a clever trick with sizeof and an array to check if there are more parameters to log. If so, it recursively calls itself with the remaining parameters.

Example Usage:

void myFunction(int x, float y, char* z) {
    LOG_PARAMS(x, y, z); 
    // ... rest of your function code
}

int main() {
    myFunction(10, 3.14, "hello");
    return 0;
}

Output:

myFunction(x = 0x7ff... , y = 0x7ff..., z = 0x7ff...)

Key Points:

  • Pointers: This macro prints the memory addresses (pointers) of the parameters. For basic types like int or float, you'll see their values directly. For more complex types (structs, arrays), you'll see their memory addresses. You might need to add custom logic within the macro to handle specific types if you want to print their contents directly.
  • Error Handling: This macro doesn't include extensive error handling (e.g., checking for NULL pointers). You might want to add such checks if your code requires them.
  • Portability: __func__ is widely supported, but its exact behavior might vary slightly across compilers.
Clone this wiki locally