1

I have a function which I want to convert to a macro without violating type safety

#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);
}

I try to replace getAddress() function with this macro. I know this macro definition is wrong.

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

I read this post Macro vs Function in C But still couldn't figure how to do it for this case

Community
  • 1
  • 1
arunmoezhi
  • 3,082
  • 6
  • 35
  • 54

1 Answers1

1

This is almost equivalent, except that the macro is more permissive than the function when type-checking its argument:

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

Some C compilers accept static inline, that's not a macro, but it's equivalent to the original function, and will get inlined most of the time in practice:

static inline struct node* getAddress(struct node* p) {
  return (struct node*)((uintptr_t) p & UINTPTR_MAX_XOR_WITH_1);
}
pts
  • 80,836
  • 20
  • 110
  • 183
  • thanks. It worked perfect. I'm using `gcc` with `-O3` flag enabled. Since this is a one line function I expected it to get inlined during compilation – arunmoezhi Mar 12 '14 at 23:17
  • What does the _double_ cast to `p` do? – Joseph Quinsey Mar 12 '14 at 23:47
  • @JosephQuinsey: I think you are right. `(uintptr_t) (p)` would be fine. Since `p` is of type `struct node*`, it it redundant to typecast it again – arunmoezhi Mar 13 '14 at 07:12
  • @arunmoezhi: In this case it's indeed redundant, but in general it's useful to start with typecasting the macro argument, to make sure that it is of the type we expect. – pts Mar 13 '14 at 13:17
  • @pts: Thanks. I understand. You did that as a sanity check. – arunmoezhi Mar 13 '14 at 19:04