簡體   English   中英

在預處理器指令中使用比較運算符 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包括 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM