根据宏中的条件选择struct-member

时间:2014-10-11 03:13:25

标签: c c-preprocessor conditional-operator

我对C有点新意,所以我还在学习绳索。我无法让预处理器宏按照我想要的方式工作。在这种情况下,我有一个这样的结构:

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

我想创建一个像这样的宏:

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

这样我就可以做这样的事情:

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

但那不太合适。

为什么它不起作用,我怎么能纠正它?

4 个答案:

答案 0 :(得分:4)

以这种方式改变它(三元运算符永远不会在C中返回左值):

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

的变化:

  • 在选项上使用地址,并取消引用条件运算符的结果。
  • 添加了缺少的括号。

但请注意,s将被评估两次。 (你可以使用内联函数或依赖于实现的魔法来解决这个问题。)

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

答案 1 :(得分:0)

创建一个允许你编写一个类似函数调用的赋值的宏很糟糕。仅仅因为你可以做某事并不代表你应该做的事。

编写内联函数比使用宏更好地处理这类事情,并且更容易完全正确。

答案 2 :(得分:0)

你可以#define一个SETDATA()宏,它将非常相似,并且可以工作:

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

答案 3 :(得分:0)

在C中,你必须使用指针通过三元组。您的代码将在C ++中按原样运行(但是,在C ++中,您可以从函数返回引用)。

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

我在s附近添加了括号,但仍存在多重评估问题。