nuriaion
nuriaion

Reputation: 2631

Macro questions

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

Answers (6)

Steve Melnikoff
Steve Melnikoff

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

ephemient
ephemient

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

Fred Larson
Fred Larson

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

JaredPar
JaredPar

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

anon
anon

Reputation:

Why are you storing the inverse when it can be so easily calculated? This seems like a bad idea to me.

Upvotes: 4

plinth
plinth

Reputation: 49179

#define SetInverse(token, value) { token = value; token##_inverse = ~value; }

Jinx, Jared - like the while (0) in yours

Upvotes: 1

Related Questions