Reputation: 2631
On a software project (some old C compiler) we have a lot of variables which have to be saved normal and inverted.
Has somebody a idea how i can make a macro like that?
SET(SomeVariable, 137);
which will execute
SomeVariable = 137;
SomeVariable_inverse = ~137;
Edit:
The best Solution seems to be:
#define SET(var,value) do { var = (value); var##_inverse = ~(value); } while(0)
Thanks for the answers
Upvotes: 2
Views: 635
Reputation: 2670
Just to offer an alternative method:
Store each variable as a structure like this:
typedef struct
{
u32 u32Normal;
u32 u32Inverted;
} SafeU32TYPE
Then have a function which takes a pointer to one of these, along with the value to be set, and stores that value with its inverse:
void Set(SafeU32TYPE *pSafeU32, u32Data)
{
if(pSafeU32 != NULL)
{
pSafeU32->u32Normal = u32Data;
pSageU32->u32Inverted = ~u32Data;
} /* if */
} /* Set() */
Advantage: if you need the set function to do something more powerful, such as boundary checking, or storing in some more complex way, then it can be easily extended.
Disadvantage: you'll need a different function for each type used, and if processor resource is an issue, this is less efficient than using a macro.
Upvotes: 0
Reputation: 204678
You can do it in a single statement, which avoids having to use do {} while (0)
.
#define SetInverse(token, value) (token##_inverse = ~(token = (value)))
Also, this only evalutes (value)
once, which is always nice.
Upvotes: 4
Reputation: 62053
One hazard I haven't seen mentioned is that the 'value' macro argument is evaluated twice in most of the solutions. That can cause problems if someone tries something like this:
int x = 10;
SET(myVariable, x++);
After this call, myVariable would be 10 and myVariable_inverse would be ~11. Oops. A minor change to JaredPar's solution solves this:
#define SET(var,value) do { var = (value); var##_inverse = ~(var); } while(0)
Upvotes: 5
Reputation: 754545
Try this
#define SET(var,value) do { var = (value); var##_inverse = ~(value); } while(0)
EDIT
Couple of links to the reason behind adding a do/while into the macro
Upvotes: 11
Reputation:
Why are you storing the inverse when it can be so easily calculated? This seems like a bad idea to me.
Upvotes: 4
Reputation: 49179
#define SetInverse(token, value) { token = value; token##_inverse = ~value; }
Jinx, Jared - like the while (0) in yours
Upvotes: 1