[英]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_t
和uint_fast16_t
,以便在使用比特寬度(如uint_fast16_t
等)的稀有平台上運行代碼。
絕對可能,是的。 在我的筆記本電腦(英特爾Haswell)上,在一個微基准測試中,在兩個寄存器上向上和向下計數0到65535,這需要20億次
1.313660150s - ax dx (16-bit) 1.312484805s - eax edx (32-bit) 1.312270238s - rax rdx (64-bit)
微不足道但可重復的時間差異。 (我在匯編中編寫了基准測試,因為C編譯器可能會將其優化為不同的寄存器大小。)
它會工作,但如果你改變邊界你就必須保持最新,C編譯器可能會將它優化為相同的匯編代碼。
只要它是正確的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. }
是。 此外,POSIX提供了inttypes.h
,它使用一些有用的函數和宏擴展了stdint.h
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.