John Lawrence Aspden
John Lawrence Aspden

Reputation: 17470

Is there a C preprocessor macro to print out a struct?

As far as I can tell, there's no way to print out a struct value in C.

i.e., this doesn't fly:

typedef struct {
    int a;
    double b;
} stype

stype a;

a.a=3;
a.b=3.4;

printf("%z", a);

instead you have to say:

printf("a: %d\n", a.a);
printf("b: %f\n", a.b);

This seems like a perfect place where you could use a macro to save a vast amount of typing for arbitrary structs.

Is the C preprocessor powerful enough to perform this transformation?

Upvotes: 2

Views: 5236

Answers (6)

Tomas Pruzina
Tomas Pruzina

Reputation: 8887

You could make macro for this:

#define PRINT_MEMBER(M) do {printf(#M": %d\n", (int) M;} while(0)

and then print it like this:

PRINT_MEMBER(a.a);
PRINT_MEMBER(b->b);

You might wanna define multiple of these to cover different types (e.g. floats, doubles, print as hex). Unfortunately there is no good workaround for this as C preprecossor has no notion of what types are, e.g. you can't use something like switch(typeof(M)) { case int: printf(.."%d"..; break; ...} .

Upvotes: 1

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215287

I would make two macros, like this:

#define STYPE_FMT "%d %f"
#define STYPE_MEMS(s) (s).a, (s).b

Then you can do something like:

printf("hello %s, stype: " STYPE_FMT "\n", "world", STYPE_MEMS(my_s));

What makes this approach superior to a "print function" for the structure is that you can use the macros with any of the printf-family functions you like, and combine printing of other data.

You could get even fancier and instead do:

#define STYPE_FMT "%d %.*f"
#define STYPE_MEMS(s) (s).a, 6, (s).b
#define STYPE_MEMS_PREC(s, p) (s).a, (int)(p), (s).b

and then you can use the default precision or choose a custom precision.

Upvotes: 7

Jean
Jean

Reputation: 483

You cannot iterate on struct members in C, either dynamically or statically (nor in C++). There is no reflection in C.

Thus, there is no way to make the preprocessor perform this transformation.

Upvotes: 1

Sandro Munda
Sandro Munda

Reputation: 41030

I think that the simplest solution (and maybe the most beautiful) is to use a function to print your specific struct.

void display_stype(stype *s)
{
    printf("a: %d\n", s->a);
    printf("b: %f\n", s->b);
}

If your struct changed, you can adapt in one place your code easily.

Upvotes: 4

K-ballo
K-ballo

Reputation: 81349

Is the C preprocessor powerful enough to perform this transformation?

Yes, it is, but then you have to repeat the entire struct declaration within the macro which kind of defeats the purpose. You could have something like this:

STRUCT_PRINTF(
    a
  , ( int, a )
    ( double, b )
);

and then you would need a pretty complex implementation of such macro, with lots and lots of helper macros/functions.

Upvotes: 3

Juliano
Juliano

Reputation: 41397

No, the C preprocessor is mostly a textual macro replacement tool. It doesn't know about types and structures of C.

Upvotes: 3

Related Questions