【问题标题】:Select struct-member dependent on a condition in a macro根据宏中的条件选择结构成员
【发布时间】:2014-12-06 06:54:15
【问题描述】:

我对 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. 

但这并不完全奏效。

为什么它不起作用,我该如何纠正它?

【问题讨论】:

  • 有线,但很有趣 +1。但是为什么要getdata?您有什么想要完成完成的吗?

标签: c c-preprocessor conditional-operator


【解决方案1】:

这样改(三元运算符从不返回 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))

【讨论】:

    【解决方案2】:

    创建一个宏来让你写一个看起来像函数调用的赋值是很糟糕的。仅仅因为你可以做某事并不意味着你应该这样做。

    在这种情况下,编写内联函数比使用宏要好得多,而且更容易完全正确。

    【讨论】:

    • 是的,这个想法更多是为了娱乐/学习,而不是出于任何严肃的原因。
    • 当然。这也是我的第一反应。作为评论,这是有价值的,但它不能回答问题。
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

      我在s 周围添加了括号,但仍然存在多重评估问题。

      【讨论】:

      • 我的回答是在几秒钟之后,但它更完整。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多