2014-03-12 30 views
1

我有我要轉換爲宏而不違反類型安全轉換一個行函數宏在C

#define UINTPTR_MAX_XOR_WITH_1 (uintptr_t) (UINTPTR_MAX^1) 
struct node 
{ 
    unsigned long key; 
    tbb::atomic<struct node*> lChild; //format <address,flagBit> 
    tbb::atomic<struct node*> rChild; //format <address,flagBit> 
}; 

struct node* getAddress(struct node* p) 
{ 
    return (struct node*)((uintptr_t) p & UINTPTR_MAX_XOR_WITH_1); 
} 

main() 
{ 
    nodeAddr = getAddress(node); 
    lNodeAddr = getAddress(node->lChild); 
} 

我嘗試用這個宏替換getAddress()功能的功能。我知道這個宏定義是錯誤的。

#define getAddress(p) ((struct node*) (uintptr_t) p & UINTPTR_MAX_XOR_WITH_1) 

我看到這篇文章 Macro vs Function in C 但還是沒能弄清楚如何做到這一點對於這種情況

+0

該函數肯定比宏好。而你的主要是相當時髦。 –

+0

爲什麼認爲這個函數比一個宏好。主要更復雜。我只是把相關的代碼放在這裏:) – arunmoezhi

+0

宏通常更糟。你爲什麼喜歡他們? –

回答

1

這幾乎是等價的,不過宏比功能更寬容時類型檢查它的參數:

#define getAddress(p) ((struct node*) ((uintptr_t) (struct node*)(p) & UINTPTR_MAX_XOR_WITH_1)) 

一些C編譯器接受static inline,這不是一個宏,但它等同於原有的功能,並且將獲得內聯大部分時間在實踐中:

static inline struct node* getAddress(struct node* p) { 
    return (struct node*)((uintptr_t) p & UINTPTR_MAX_XOR_WITH_1); 
} 
+0

謝謝。它工作完美。我在啓用'-O3'標誌的情況下使用'gcc'。由於這是一個單行函數,我預計它在編譯期間會被內聯 – arunmoezhi

+0

_double_ cast對'p'做了什麼? –

+0

@JosephQuinsey:我認爲你是對的。 '(uintptr_t)(p)'會很好。由於'p'是'struct node *'的類型,因此再次對它進行類型轉換是多餘的 – arunmoezhi