2013-09-10 47 views
3

我有一個變量id,其類型可能因平臺而異。在幾個地方,現有代碼(我不能改變)將id設置爲「負」值,例如,比較未知類型和負值

id = -ETIMEDOUT; 

在某些平臺上,可能會對id進行簽名;在其他方面,它可能是未簽名的。我想測試看看id是否設置爲-ETIMEDOUT

if(id == -ETIMEDOUT) 

如何簡潔地測試這種情況:當id是無符號下方巧妙的天真嘗試失敗?

+2

爲什麼不只是測試'if(id ==(idtype)-ETIMEDOUT)',其中'idtype'是什麼類型'id'被聲明爲(可能是'typedef')? –

回答

2

@jlahd發佈了一個很好的答案。但我想提供一個替代方案。

if (id == (typeof(id)) -ETIMEDOUT) 

我認爲這會做類似的事情,但它有問題。它不在C標準中,並且是GCC擴展。

你可以閱讀更多有關這個問題的here

@ RICI的評論逐字引用:

因爲你很可能知道一些typedef,它可以作爲ID的類型,你可以大概做這沒有typeof,雖然這是更清潔。然而,它應該是

(typeof(id))(-ETIMEDOUT) 

(約-ETIMEDOUT括號只是裝飾,但需要一元減。)另外,下面應該是相當不錯萬無一失:

if (-id == ETIMEDOUT) 

因爲如果id是有符號的,那顯然有效;如果id是無符號的,則一元減號具有定義良好的行爲。

+1

既然你可能知道一些typedef作爲'id'的類型,你可以假設沒有'typeof',儘管這樣做更清晰。但是,它應該是'(typeof(id))( - ETIMEDOUT)'('-ETIMEDOUT'周圍的括號只是表達式,但一元減號是必需的。)或者,下面的代碼應該非常簡單:if( - id == ETIMEDOUT)',因爲如果'id'被簽名,那顯然是有效的;如果'id'是無符號的,則一元減號具有明確的行爲。 – rici

+0

@rici我非常喜歡你的評論,如果你不介意的話,我會逐字將其包含在我的答案中。 – nonsensickle

+0

@rici如果您決定將此作爲您自己的答案,請讓我知道,我將刪除該編輯。這裏的評論可能是引起我注意的最好方法。 – nonsensickle

2

試試這個:

id += ETIMEDOUT; 
if(id == 0) { /* timed out */ } 
id -= ETIMEDOUT; /* if you need to keep id untouched */ 
+0

Lol,在任何人有機會說這不適用於「非二補的算術機器」之前,我想請他們在發佈答覆之前命名今天正在使用的一個... – nonsensickle

+0

@nonsensical:好吧,實際上,如果你溢出了一個有符號的整數,它就是UB。即使系統是二補的,編譯器也可以在這種情況下做「意想不到的事情」。 – nneonneo

+0

+1 - 這種解決方案是合理的,但它有點麻煩,特別是如果我不得不最終測試六打errnos。 – nneonneo