Select the struct-member depending on the condition in the macro

I'm a bit new to C, so I'm still learning ropes. I'm having trouble getting the macro preprocessor to work the way I want it to. Here's the situation, I have a structure like this:

struct super {
    int data1;
    int data2;
    int condition;
};

      

and I would like to create a macro like this:

#define getdata(s) (s.condition ? s.data1 : s.data2)

      

so that I can do things like this:

getdata(s) = 4 // stores in data1 if condition, data2, if not. 

      

But that doesn't quite work.

Why is this not working and how can I fix it?

+3


source to share


4 answers


Modify it this way (ternary operator never returns an lvalue in C):

#define getdata(s) (*((s).condition ? &(s).data1 : &(s).data2)

      

Changes:



  • Using the address from the options and dereferencing the result of the conditional operator.
  • Added missing parentheses.

Remember, it s

will be evaluated twice. (You can work around this with built-in function or implementation dependent magic).

inline int* getdata(struct super* s) {return s->condition ? &s->data1 : &s->data2;}
#define getdata(s) (*getdata(&s))

      

+4


source


Creating a macro that allows you to write an assignment to what looks like a function call is just awful. Just because you can do something doesn't mean you need to.



Writing inline functions is much better for this kind of thing than using a macro, and it's much easier to get it perfectly right.

0


source


You can # define a SETDATA () macro that is very similar and will work:

#define SETDATA(s,n) ( s.condition ? s.data1 = n : s.data2 = n )

      

0


source


In C, you have to use a pointer via ternary. Your code will work as it is in C ++ (but then, in C ++, you can return a reference from a function).

#define getdata(s) *((s).condition ? &(s).data1 : &(s).data2)

      

I have added parentheses around s

, but there is still a multiple grades issue.

0


source







All Articles