-
Notifications
You must be signed in to change notification settings - Fork 2
FAQ: C Macro that prints structure fields
Ulrond edited this page Aug 8, 2024
·
1 revision
This macro prints the structure name, field names, and their corresponding values:
#include <stdio.h>
#define LOG_STRUCT(structVar) \
do { \
printf("Structure: %s\n", #structVar); \
_log_struct_helper(structVar); \
} while (0)
#define _log_struct_helper(structVar) \
_log_struct_fields_helper(structVar, _get_struct_fields(structVar))
#define _get_struct_fields(structVar) \
_get_struct_fields_helper(0, structVar)
#define _get_struct_fields_helper(index, structVar) \
_Generic((structVar), \
default: _get_struct_fields_helper(index + 1, structVar), \
char: #structVar.index, \
int: #structVar.index, \
float: #structVar.index, \
double: #structVar.index, \
char *: #structVar.index, \
int *: #structVar.index, \
float *: #structVar.index, \
double *: #structVar.index \
)
#define _log_struct_fields_helper(structVar, fieldName, ...) \
do { \
printf(" %s = ", fieldName); \
_print_field_value(structVar.index); \
if (sizeof((int[]){__VA_ARGS__})/sizeof(int) > 0) { \
printf("\n"); \
_log_struct_fields_helper(structVar, __VA_ARGS__); \
} \
} while (0)
#define _print_field_value(fieldValue) \
_Generic((fieldValue), \
char: printf("%c", fieldValue), \
int: printf("%d", fieldValue), \
float: printf("%f", fieldValue), \
double: printf("%lf", fieldValue), \
char *: printf("%s", fieldValue), \
default: printf("%p", (void*)fieldValue) \
)Explanation
-
LOG_STRUCT: This is the main macro that you'll use. It takes the structure variable as input and prints the structure's name. -
_log_struct_helper: This helper function recursively processes the structure fields. -
_get_struct_fields: This helper function uses_Genericto determine the types of fields in the structure and generates a list of field names. -
_log_struct_fields_helper: This helper function iterates over the list of field names, prints each field name and its value using_print_field_value. -
_print_field_value: This helper function uses_Genericto print the field value based on its type. It handles basic types likechar,int,float,double, and pointers to these types. For other types, it prints the memory address.
Example Usage
typedef struct {
int id;
char name[50];
float price;
} Product;
int main() {
Product p = {1, "Sample Product", 9.99};
LOG_STRUCT(p);
return 0;
}Output
Structure: p
id = 1
name = Sample Product
price = 9.990000
Key Points:
-
Limited Type Support: The macro currently supports basic types (
char,int,float,double) and pointers to these types. You can extend it to handle other types by adding more cases to the_Genericexpressions in_get_struct_fields_helperand_print_field_value. - Nested Structures: The macro does not currently handle nested structures. You would need to add more logic to recursively process nested structures if required.
- Arrays: The macro handles arrays of basic types by printing their memory address. To print the individual elements of an array, you'll need to add custom logic.