在预处理器指令 C++ 中使用比较运算符
Using Comparison Operators in preprocessor directives C++
我想定义一些基于常数值的函数:
#define mode 5
#if mode & 2 != 0
// function 1
#endif
#if mode & 4 != 0
// function 2
#endif
这听起来和看起来很奇怪,但我想使用一个常量来定义和激活一些程序模块。
定义 mode = 2
包括函数 1,mode = 4
包括函数 2,mode = 6
包括两个函数。
存在一个问题:==
、!=
、>
或 <
等比较运算符似乎在指令中不起作用,并且总是执行 #if
语句。
我做错了什么?我是不是想做一件愚蠢或不可能的事情?
&
的 precendence 低于 !=
。所以:
MODE & 2 != 0
与
相同
MODE & (2 != 0)
2 != 0
逻辑上为真,所以!=
运算符的结果是1
。因此这与
相同
MODE & 1
它只是检查第一位。当你想要的时候:
(MODE & 2) != 0
检查是否设置了第二位。但实际上只需删除 !=
部分并执行:
#if MODE & 2
记得prefer upper case names for macro names.
This may sound and look weird
不,这听起来很正常。我会使用更多描述性的名称,然后普通的 & 2
- magic numbers 会令人困惑。喜欢:
#define MODE (MODE_ENABLE_FUNC_1 | MODE_ENABLE_FUNC_2)
#define MODE_ENABLE_FUNC_1 (1<<0)
#define MODE_ENABLE_FUNC_2 (1<<1)
#define MODE_ENABLE_FUNC_3 (1<<2)
#define MODE_IS_ENABLED(mode, feature) ( ((mode) & (feature)) != 0)
#if MODE_IS_ENABLED(MODE, MODE_ENABLE_FUNC_1)
// etc.
如果可能,更喜欢使用 C++ 模板和 SFINAE,而不是普通的 C 宏。
What am I doing wrong?
您假设 !=
的优先级低于 &
。
Am I trying to do a stupid or impossible thing?
没有
我记得 The development of C language by Dennis M. Ritchie 部分和章节名称 Neonatal C
他写道:
[...] In converting from B to C, one wants to replace & by && in such a statement; to make the conversion less painful, we decided to keep the precedence of the & operator the same relative to ==, and merely split the precedence of && slightly from &. Today, it seems that it would have been preferable to move the
relative precedences of & and ==, and thereby simplify a common C
idiom: to test a masked value against another value, one must write
if ((a&mask) == b) ...
where the inner parentheses are required but easily forgotten.
不用担心 - 您不是第一个也不是最后一个忘记 &
和另一个运算符上下文中的大括号的人。
我想定义一些基于常数值的函数:
#define mode 5
#if mode & 2 != 0
// function 1
#endif
#if mode & 4 != 0
// function 2
#endif
这听起来和看起来很奇怪,但我想使用一个常量来定义和激活一些程序模块。
定义 mode = 2
包括函数 1,mode = 4
包括函数 2,mode = 6
包括两个函数。
存在一个问题:==
、!=
、>
或 <
等比较运算符似乎在指令中不起作用,并且总是执行 #if
语句。
我做错了什么?我是不是想做一件愚蠢或不可能的事情?
&
的 precendence 低于 !=
。所以:
MODE & 2 != 0
与
相同MODE & (2 != 0)
2 != 0
逻辑上为真,所以!=
运算符的结果是1
。因此这与
MODE & 1
它只是检查第一位。当你想要的时候:
(MODE & 2) != 0
检查是否设置了第二位。但实际上只需删除 !=
部分并执行:
#if MODE & 2
记得prefer upper case names for macro names.
This may sound and look weird
不,这听起来很正常。我会使用更多描述性的名称,然后普通的 & 2
- magic numbers 会令人困惑。喜欢:
#define MODE (MODE_ENABLE_FUNC_1 | MODE_ENABLE_FUNC_2)
#define MODE_ENABLE_FUNC_1 (1<<0)
#define MODE_ENABLE_FUNC_2 (1<<1)
#define MODE_ENABLE_FUNC_3 (1<<2)
#define MODE_IS_ENABLED(mode, feature) ( ((mode) & (feature)) != 0)
#if MODE_IS_ENABLED(MODE, MODE_ENABLE_FUNC_1)
// etc.
如果可能,更喜欢使用 C++ 模板和 SFINAE,而不是普通的 C 宏。
What am I doing wrong?
您假设 !=
的优先级低于 &
。
Am I trying to do a stupid or impossible thing?
没有
我记得 The development of C language by Dennis M. Ritchie 部分和章节名称 Neonatal C
他写道:
[...] In converting from B to C, one wants to replace & by && in such a statement; to make the conversion less painful, we decided to keep the precedence of the & operator the same relative to ==, and merely split the precedence of && slightly from &. Today, it seems that it would have been preferable to move the relative precedences of & and ==, and thereby simplify a common C idiom: to test a masked value against another value, one must write
if ((a&mask) == b) ...
where the inner parentheses are required but easily forgotten.
不用担心 - 您不是第一个也不是最后一个忘记 &
和另一个运算符上下文中的大括号的人。