-
Notifications
You must be signed in to change notification settings - Fork 0
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_Generic
to 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_Generic
to 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_Generic
expressions in_get_struct_fields_helper
and_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.