在C中设置一个标志,就像在装配语言中一样优雅

Dav*_*rea 5 c flags clear c-preprocessor

与组装相比,C中的标志处理感觉很麻烦.

我正在寻找一种方法,使C代码可以像汇编一样可读.

在大会中:

#define powerOn flagsByte,0
... 
bsf powerOn ; Turn on the power
bcf powerOn ; Turn off the power
btfsc powerOn ; If the power is on...
Run Code Online (Sandbox Code Playgroud)

在C:

flagsByte |= (1 << 0) ; // Turn on the power
flagsByte &= ~(1 << 0) ; // Turn off the power
if (flagsByte & (1 << 0)); // If the power is on...
Run Code Online (Sandbox Code Playgroud)

在C中,用宏:

#define BIT_SET(var,bitNo) (var |= (1<<(bitNo)))
BIT_SET(flagsByte,0) ; // Turn on the power
Run Code Online (Sandbox Code Playgroud)

这可行,但它仍然不如装配中那么干净.

我喜欢这样做:

#define powerOn flagsByte,0
BIT_SET(powerOn) ; // Turn on the power
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为它扩展到:

flagsByte,0 |= (1<<())
Run Code Online (Sandbox Code Playgroud)

代替:

flagsByte |= (1<<(0))
Run Code Online (Sandbox Code Playgroud)

题:

在C中是否有一种优雅的方式来设置,清除或测试定义如下的标志?

#define powerOn flagsByte,0
Run Code Online (Sandbox Code Playgroud)

ric*_*ici 4

就我个人而言,我更喜欢位字段语法,并且没有宏,因为我的标志几乎总是在结构内部。但是,如果您坚持用 C 语言编写汇编程序,请按以下步骤操作:

/* We need to indirect the macro call so that the pair of arguments get expanded */
#define BITSET_(f,i) do{f|= 1<<(i);}while(0)
#define BITCLR_(f,i) do{f&=~(1<<(i));}while(0)
#define BITCHK_(f,i) ((f)&(1<<(i)))

#define BITSET(fi) BITSET_(fi)
#define BITCLR(fi) BITCLR_(fi)
#define BITCHK(fi) BITCHK_(fi)

/* Define the flag container and bit number as per OP */
#define poweron flags1,0
#define warnuser flags7,4

/* Sample uses */
BITSET(poweron);
BITCLR(warnuser);
/* Since BITCHK expands to a parenthesized expression, I can get away with
 * leaving out the parentheses in the if statement. Not saying that's a good
 * idea or anything.
 */
if BITCHK(poweron) BITSET(warnuser);
Run Code Online (Sandbox Code Playgroud)

如果你有 gcc,你可以用以下命令验证这一点gcc -E flag_macros.c