[英]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
包括 function 1, mode = 4
包括 function 2 和mode = 6
包括兩個功能。
存在一個問題: ==
、 !=
、 >
或<
等比較運算符似乎在指令中不起作用,並且總是執行#if
語句。
我究竟做錯了什么? 我是不是想做一件愚蠢或不可能的事?
&
的優先級低於!=
。 所以:
MODE & 2 != 0
是相同的
MODE & (2 != 0)
2 != 0
在邏輯上為真,所以!=
運算符的結果是1
。 因此這與
MODE & 1
它只是檢查第一位。 當你想要的時候:
(MODE & 2) != 0
檢查第二位是否已設置。 但實際上只需刪除!=
部分並執行以下操作:
#if MODE & 2
記住 宏名稱最好使用大寫名稱。
這聽起來和看起來很奇怪
不,這聽起來很正常。 我會 go 使用更多描述性名稱,然后是普通& 2
-幻數令人困惑。 像:
#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 宏。
我究竟做錯了什么?
您假設!=
的優先級低於&
。
我是不是想做一件愚蠢或不可能的事?
不。
我記得Dennis M. Ritchie的 C 語言的發展部分和Neonatal C
部分,他寫道:
[...] 在從 B 轉換為 C 時,人們希望在這樣的語句中用 && 替換 &; 為了減少轉換的痛苦,我們決定保持 & 運算符相對於 == 的優先級相同,只是將 && 的優先級與 & 略微分開。 今天,移動 & 和 == 的相對優先級似乎更可取,從而簡化了一個常見的 C 習語:要針對另一個值測試屏蔽值,必須寫
if ((a&mask) == b)...
需要內括號但很容易忘記的地方。
不用擔心 - 您不是第一個也不是最后一個忘記&
和另一個運算符上下文中的大括號的人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.