-
Couldn't load subscription status.
- Fork 2
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_helperto handle the actual parameter logging.
- It uses
-
_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
sizeofand an array to check if there are more parameters to log. If so, it recursively calls itself with the remaining parameters.
- It takes a parameter name and its value, prints them in the format
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
intorfloat, 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.