Glibc allows you to establish your own format specifiers for printf and family to let you print UDTs, which would not otherwise be possible, through some extensions.
#include <stdio.h>
#include <printf.h> /* For PA_POINTER */
struct MyStruct
{
int a;
double b;
};
struct print_info;
int handler(FILE *stream, const struct print_info *i,
const void* const *args)
{
const struct MyStruct *ptr = *( (const struct MyStruct**) (*args) );
int rc = fprintf(stream, "a: %d, b: %f\n", ptr->a, ptr->b);
return rc;
}
int print_arginfo (const struct printf_info *info, size_t n,
int *argtypes)
{
if (n > 0)
argtypes[0] = PA_POINTER;
return 1;
}
int main(void)
{
struct MyStruct s = {55, -3.14};
/* We're gonna use the M specifier */
int spec = 'M';
int rc = register_printf_function(spec, handler, print_arginfo);
if (rc != 0)
return 1;
printf("%M", &s);
};
You may find the documentation here.