chacham15 chacham15 - 2 months ago 8
C Question

How can I evaluate an argument in a preprocessor macro to pass to sizeof?

I want to have a function that prints out information about a member variable of a struct. In order to keep the function as simple (and error free) as possible I dont want to manually pass in the type as well. This causes me to need to be able to evaluate the arguments passed into my macro:

#ifndef preprocessor_stringify
#define preprocessor_stringify(s) #s
#endif

typedef struct test_s {
void (*ptr)(void*);
} test;

void doSomething_(char *name, int offset, int size){
printf("%s %d %d\n", name, offset, size);
}

#define doSomething(name, container) (\
doSomething_(\
preprocessor_stringify(name),\
offsetof(container, name),\
sizeof(container->name))\
);

int main(){
doSomething(ptr, test);
return 0;
}


This yields a compile error of
test.cpp:21:19: error: expected primary-expression before ‘->’ token
sizeof(container->name))\


Any ideas on how to fix this? I would like the solution to be both c and c++ compatible, ideally.

Answer Source
#include <stdio.h>
#include <stddef.h>

#ifndef preprocessor_stringify
#define preprocessor_stringify(s) #s
#endif

typedef struct test_s {
    void (*ptr)(void*);
} test;

void doSomething_(char const *name, int offset, int size){
    printf("%s %d %d\n", name, offset, size);
}

#define doSomething(name, container) (\
    doSomething_(\
        preprocessor_stringify(name),\
        offsetof(container, name),\
        sizeof(((container*)0)->name))\
    );

int main(){
    doSomething(ptr, test);
    return 0;
}

I have made two changes:

  1. In c++, string literals are const char[]

 

void doSomething_(char const *name, int offset, int size){
  1. We want the sizeof a model object, so we have to make a model:

 

sizeof(((container*)0)->name))\