簡體   English   中英

我應該在32/64位機器上使用stdint.h整數類型嗎?

[英]Should I use the stdint.h integer types on 32/64 bit machines?

關於常規c整數聲明讓我煩惱的一件事是他們的名字很奇怪,“很久很久”是最糟糕的。 我只是為32位和64位機器構建,所以我不一定需要庫提供的可移植性,但我喜歡每種類型的名稱是一個長度相似的單個單詞,大小沒有歧義。

// multiple word types are hard to read
// long integers can be 32 or 64 bits depending on the machine

unsigned long int foo = 64;
long int bar = -64;

// easy to read
// no ambiguity

uint64_t foo = 64;
int64_t bar = -64;

在32位和64位機器上:

1)可以使用較小的整數(如int16_t)比較高的整數(如int32_t)慢嗎?

2)如果我需要一個for循環只運行10次,是否可以使用可以處理它的最小整數而不是典型的32位整數?

for (int8_t i = 0; i < 10; i++) {

}

3)每當我使用一個我知道永遠不會是負數的整數時,即使我不需要提供的額外范圍,也可以選擇使用無符號版本嗎?

// instead of the one above
for (uint8_t i = 0; i < 10; i++) {

}

4)對stdint.h中包含的類型使用typedef是否安全

typedef int32_t signed_32_int;
typedef uint32_t unsigned_32_int;

編輯:兩個答案都同樣好,我不能真正傾向於一個所以我只選擇了較低代表的回答者

可以使用較小的整數(如int16_t)比較高的整數(如int32_t)慢嗎?

是。 有些CPU沒有專用的16位算術指令; 必須使用以下行的指令序列模擬16位整數的算術運算:

r1 = r2 + r3
r1 = r1 & 0xffff

同樣的原則適用於8位類型。

使用<stdint.h>的“快速”整數類型來避免這種情況 - 例如, int_fast16_t將給出一個至少 16位寬的整數,但如果16位類型不是最佳的,則可能更寬。

如果我需要一個for循環只運行10次,是否可以使用可以處理它的最小整數而不是典型的32位整數?

不要打擾; 只需使用int 使用較窄的類型實際上並不會節省任何空間,如果您決定將迭代次數增加到127並且忘記循環變量使用的是窄類型,則可能會導致問題。

每當我使用一個我知道永遠不會是負數的整數時,即使我不需要提供的額外范圍,也可以選擇使用無符號版本嗎?

最好避免。 某些C語言在無符號整數上不能正常工作; 例如,你不能寫一個表格的循環:

for (i = 100; i >= 0; i--) { … }

如果i是無符號類型,因為i >= 0將永遠為真!

對stdint.h中包含的類型使用typedef是否安全

從技術角度看是安全的,但它會讓其他需要使用代碼的開發人員感到煩惱。

習慣了<stdint.h>名字。 它們是標准化的,並且相當容易打字。

1)可以使用較小的整數(如int16_t)比較高的整數(如int32_t)慢嗎?

是的,它可能會更慢。 請改用int_fast16_t 根據需要配置代碼。 性能非常依賴於實現。 int16_t一個主要好處是它在結構和數組中使用的小的,定義良好的大小(也必須是2的補碼),而不是速度。

typedef名稱int_fastN_t指定寬度至少為N的最快有符號整數類型。 C11§7.20.1.32


2)如果我需要一個for循環只運行10次,是否可以使用可以處理它的最小整數而不是典型的32位整數?

是的,但代碼和速度的節省是值得懷疑的。 建議使用int 使用本機int大小,發出的代碼在速度/大小方面往往是最佳的。


3)每當我使用一個我知道永遠不會是負數的整數時,即使我不需要提供的額外范圍,也可以選擇使用無符號版本嗎?

當數學是嚴格無符號時(例如使用size_t數組索引),首選使用某些無符號類型,但代碼需要注意粗心的應用程序,如

for (unsigned i = 10 ; i >= 0; i--) // infinite loop

4)對stdint.h中包含的類型使用typedef是否安全

幾乎總是。 int16_t這樣的類型是可選的。 最大可移植性使用所需類型uint_least16_tuint_fast16_t ,以便在使用比特寬度(如uint_fast16_t等)的稀有平台上運行代碼。

  1. 絕對可能,是的。 在我的筆記本電腦(英特爾Haswell)上,在一個微基准測試中,在兩個寄存器上向上和向下計數0到65535,這需要20億次

     1.313660150s - ax dx (16-bit) 1.312484805s - eax edx (32-bit) 1.312270238s - rax rdx (64-bit) 

    微不足道但可重復的時間差異。 (我在匯編中編寫了基准測試,因為C編譯器可能會將其優化為不同的寄存器大小。)

  2. 它會工作,但如果你改變邊界你就必須保持最新,C編譯器可能會將它優化為相同的匯編代碼。

  3. 只要它是正確的C,那就完全沒問題了。 請記住,定義了無符號溢出,並且未定義有符號溢出,編譯器確實利用它進行優化。 例如,

     void foo(int start, int count) { for (int i = start; i < start + count; i++) { // With unsigned arithmetic, this will execute 0 times if // "start + count" overflows to a number smaller than "start". // With signed arithmetic, that may happen, or the compiler // may assume this loop always runs "count" times. // For defined behavior, avoid signed overflow. } 
  4. 是。 此外,POSIX提供了inttypes.h ,它使用一些有用的函數和宏擴展了stdint.h

暫無
暫無

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

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