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)
就我个人而言,我更喜欢位字段语法,并且没有宏,因为我的标志几乎总是在结构内部。但是,如果您坚持用 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