A quick way to set a bitmask from boolean to C

Usually check and set / clear the flag, for example:

if (some_test) { flag |= SOME_FLAG; } else { flag &= ~SOME_FLAG; } 

I have found a convenient way around this so far ...

 flag = (some_test) ? (flag | SOME_FLAG) : (flag & ~SOME_FLAG); 

This can be done in a macro and its OK, but is there some tweedling magic to avoid referencing the flag twice?

(in case multiple instances of flag lead to overhead).

An example of what I'm looking for (if C can perform ternary operations with operators) ...

 flag ((some_test) ? (|=) : (&= ~) SOME_FLAG; 

The above example is intended only to describe what I am looking for, of course, it will not work in its current form.

+4
source share
3 answers
 flag |= SOME_FLAG 

is an expression, so you can use a macro

 #define SET_FLAG(flag, some_test) \ ((some_test) ? ((flag) |= SOME_FLAG) : ((flag) &= ~SOME_FLAG)) 

which evaluates flag only once, and when you use it, you need to type flag only once.

 SET_FLAG(a->b->c->d, test); 
+8
source

I know that you do not want to use the access flag twice. But you have to be sure what exactly stands there. Often, conditional conversion is more expensive. On the last embedded processor that I worked on, the fastest code would look like this:

  flag &= ~(SOME_FLAG); flag |= (some_test!=0) * SOME_FLAG; 
+3
source

If you want to define a macro and not let it evaluate the mask twice, you can do it like this:

 #define SETT(FLAG, MASK_T, MASK, TEST) \ do {\ MASK_T mask = (MASK);\ FLAG &= ~mask;\ FLAG |= ((TEST) != 0) * mask;\ }\ while(false) #define SET(FLAG, MASK, TEST) SETT(FLAG, unsigned, MASK, TEST) 
0
source

Source: https://habr.com/ru/post/1444501/


All Articles