簡體   English   中英

帶有簽名/無符號整數和函數調用的C / C ++最佳實踐

[英]C / C++ best practices with signed / unsigned ints and function calls

我問這個問題有兩種不同的語言:C和C ++。

調用具有相反整數符號期望的函數時,最佳做法是什么?

例如:

uint32       _depth;                        // uint32 = DWORD
int          depth;

_BitScanForward(&_depth, (uint32)input);    // DWORD, DWORD
depth = (int)_depth;

_BitScanForward期待DWORD(uint32)參數。 變量input是int16類型,我需要在我的代碼中將結果_depth作為int32處理。

  1. 如圖所示,我是否需要關注投射input 我知道編譯器可能會為我做,但最佳做法是什么?
  2. _depth聲明為int32是否可以接受,因此避免必須如后所示_depth轉換它?

注意:

我對編譯器的評論是基於經驗的。 我編寫的代碼在VS中沒有警告編譯但在執行時崩潰。 原來我正在調用一個incorect width int的函數。 所以我不再把這個話題留給編譯器了。

編輯:

答案很有幫助,謝謝。 讓我提煉我的問題。 如果沒有寬度問題,即函數不期望比傳入的更窄的int(obvioulsy將失敗),那么依靠編譯器處理符號和寬度差異是否可以?

我強烈建議將該函數隱藏到自定義包裝函數中,該函數與您首選的API一致(並且在此函數中進行適當的顯式轉換)。 在使用特定於編譯器的函數的情況下,這具有額外的優點,即通過重新實現該包裝函數,將它移植到不同的編譯器(如果您想要這樣做)將更容易。

從比int更窄的任何整數類型轉換為寬度相同或寬於int任何整數類型時,編寫顯式轉換非常重要。 如果不這樣做,編譯器將首先將值轉換為int ,因為“整數提升”規則,然后到目標類型。 這幾乎總是錯誤的,如果我們今天從頭開始,我們不會這樣設計語言,但為了兼容性,我們堅持使用它。

系統提供的類型定義如uint16_tuint32_tWORDDWORD可能比int更窄,更寬或相同; 在C ++中,你可以使用模板來解決它,但在C中你不能。 因此,您可能希望為涉及這些的任何轉換編寫顯式強制類型轉換。

那有點取決於你的用法等:

如果我可以使用所需的類型我只使用類型。

如果不是:您的編譯器應該在您隱式轉換可能導致上溢/下溢的數據類型的情況下發出警告。 所以我通常會有這些警告,並將隱式轉換更改為顯式轉換。

我有兩種不同的方法:

如果我100%確定我永遠不會在signed / unsigned int之間的邊界上/下溢,我使用static_cast (通常用於轉換不同的API。像size()返回int vs size_t)。

當我不確定或有可能我超出界限時我使用boost::numeric_cast 當你超越邊界時會拋出異常,從而顯示何時發生這種情況。

如果出現問題而不是繼續使用損壞的數據然后在其他地方崩潰或使用未定義的數據執行其他操作,那么具有例外的方法會堅持執行以使其失敗或崩潰/終止。

首先,您的編譯器將隱式進行強制轉換,並在任何有意義的警告級別上給出警告。

您執行的兩個強制轉換都是強制轉換,編譯器(或您的同事)無法輕易確定它們是否正確,因此使用邊界測試進行顯式轉換或顯式轉換是最佳做法。 您選擇哪種方法取決於您對數據的了解。 最安全的方法是檢查邊界條件。 最簡單的方法是簡單地轉換(在C ++中請使用static_cast而不是C風格的轉換)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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