2014-10-11 56 views
3

我對C有點新,所以我仍然在學習繩索。我無法讓預處理器宏以我想要的方式工作。這裏的情況,我有這樣的結構:根據宏中的條件選擇struct-member

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. 

但這不是很有效。

爲什麼它不起作用,我該如何糾正它?

+0

有線,但有趣的+1。但爲什麼* getdata *?有沒有你想要*做的事? – Wolf 2015-01-06 16:20:44

回答

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)) 
+0

謝謝!這工作! – ALPH 2014-10-11 03:28:40

0

創建一個允許你寫一個看起來像函數調用的分配的宏是很糟糕的。只因爲你可以做一些事情並不意味着你應該。

編寫內聯函數比使用宏要好得多,而且更容易得到完美的結果。

+0

是的,這個想法比任何嚴肅的理由更有趣。 – ALPH 2014-10-11 03:20:21

+0

絕對如此。這也是我的第一反應。作爲評論這是有價值的,但它不回答這個問題。 – Wolf 2015-01-06 16:26:51

0

可以將#define一個的SetData()宏,這將是非常相似的,並且將工作:

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

在C,你必須通過三元使用指針。你的代碼可以像C++一樣工作(但是,在C++中,你可以從函數返回一個引用)。

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

我在s的周圍加了小括號,但仍然存在多重評估問題。

+0

我的答案是幾秒鐘後,但它更完整。 – o11c 2014-10-11 03:24:06