2010-07-27 101 views
5

int類型的變量被稱爲「一個機器類型的字長」 但在嵌入式系統中,8位微的C編譯器使用16位int(8位無符號字符),然後獲取更多位, INT行爲正常: 在16位微位int也是16位,並在32位微位int是32位等。有沒有標準的方法來檢測硬件的位寬?

那麼,有沒有一個標準的方式來測試它,像BITSIZEOF(INT)?

像「sizeof」是爲字節,但爲位。

,這是我的第一個想法

register c=1;     
    int bitwidth=0; 
    do 
    { 

     bitwidth++; 

    }while(c<<=1); 

    printf("Register bit width is : %d",bitwidth); 

但是這需要C作爲int和它的8個編譯器是常見的INT 16位使用,所以它給了我16的結果,似乎也沒有標準使用「int」作爲「註冊寬度」,(或不尊重)

爲什麼我要檢測它?假設我需要許多變量,它們需要少於256個值,因此它們可以是8,16,32位,但是使用正確的大小(與內存和寄存器相同)會加快速度並節省內存,如果不能在代碼決定,我必須重新編寫函數爲每建築

編輯閱讀答案 後,我發現這個好文章

http://embeddedgurus.com/stack-overflow/category/efficient-cc/page/4/

我引用的結論(加粗體)

因此 的底線是這樣的。如果你想 開始編寫高效的,便攜的 嵌入代碼,你應該採取的第一步是開始使用C99 數據類型'最少'和'快'。如果您的 編譯器不符合C99,則 抱怨,直到它或 - 更改 供應商。如果您進行此更改I 認爲您將會驚喜 您的代碼大小和 速度將得到改進。

+2

使用像char,int,short這樣的類型是不好的做法,應該被嵌入式系統禁止。我見過一個編譯器(CodeWarrior),它允許你改變每種類型的長度。只要使用types.h頭文件即可。 – kmalmur 2010-07-27 17:59:15

回答

17

我不得不重新編寫函數爲每建築

不,你不會。使用C99的stdint.h,其類型如,這將是一種能夠保存256個值的類型,並且很快。

然後,無論平臺如何,類型都會相應地改變,並且您不會更改代碼中的任何內容。如果您的平臺沒有定義這些集合,您可以添加自己的。

遠勝於重寫每個函數。

+0

+1這是一個解決方案和更多的標準,我認爲(無論如何,我仍然無法檢測硬件的寬度) – 2010-07-27 17:55:25

+1

@赫爾南:毫不奇怪。 C不關心實現,寬度是需要使用某些特定於操作系統的API暴露的事情。 – GManNickG 2010-07-27 18:00:51

+0

Codewarrior編譯器似乎不符合C99,我將遵循embeddedgurus.com的建議,抱怨或改變供應商= P – 2010-07-27 19:13:02

1

您編譯的ISA在編譯器運行時已經知道,所以最好的選擇是在編譯時檢測它。根據你的環境,你可以使用從autoconf/automake風格的東西到更低級別的所有東西#ifdef來調整你的代碼到它將要運行的特定架構。

+1

複雜的方式。按照Paul和Andrey的建議,使用'sizeof(int)* CHAR_BIT'。 – sbi 2010-07-27 17:44:07

7
#include <limits.h> 

const int bitwidth = sizeof(int) * CHAR_BIT; 
+1

-1'int'的寬度不是OP正在尋找的內容... – 2012-03-20 05:40:48

1

我完全不明白你的意思是「沒有使用任何STANDAR‘詮釋’爲‘註冊寬度’,在原來的C語言規範(C89/90)的類型int是隱含在在沒有明確類型的情況下,你的register c相當於register int c,這在C89/90中是完全標準的。還要注意C語言規範要求類型int支持至少-32767 ... + 32767範圍,這意味着任何平臺int將至少有16個值形成位。

至於位寬...sizeof(int) * CHAR_BIT會給你int類型的對象表示中的位數。

理論上,int類型的值表示不保證使用其對象表示的所有位。如果您需要確定用於值表示的位數,則可以簡單地分析INT_MININT_MAX值。

P.S.看看你的問題的標題,我懷疑你真正需要的只是CHAR_BIT的價值。

+0

問題是,在16位或8位體系結構中,CHAR_BIT,INT_MIN和INT_MAX具有相同的值,因此我無法將其用於檢測,至少在大多數常用的微量控制器編譯器中。我認爲int的標準是從16位開始的 – 2010-07-27 17:42:01

+0

@Hernán:你是說在這些架構上使用'CHAR_BIT == INT_MIN == INT_MAX'嗎?這是荒謬的!確定任何類型「T」的比特數的標準符合方式是「sizeof(T)* CHAR_BIT」。 – sbi 2010-07-27 17:46:21

+0

@sbi,它們在這個意義上有相同的值,CHAR_BIT(8位)= CHAR_BIT(16位),INT_MIN(8位)= INT_MIN(16位)等等。 – 2010-07-27 17:51:45

0

請問unsigned charunsigned short是否符合您的需求?爲什麼不使用它?如果沒有,你應該使用編譯時間標誌來引入適當的代碼。

+0

轉換爲/從默認機器字大小時會有開銷,所以使用盡可能小的變量不是最好的方式 – 2010-07-28 12:31:40

7

更直接地回答你的更深層次的問題,如果你有需要一種可以跨平臺移植非常具體的存儲大小,你應該使用類似 types.h stdint.h定義與位數指定的存儲類型。

例如,uint32_t總是無符號的32位,而int8_t總是帶有8位的符號。

+0

+1這是一個解決方案(無論如何,我仍然無法檢測到硬件的寬度) – 2010-07-27 17:54:51

+0

Isn'那麼'unint32_t'是最少_32位? ICBWT。 – sbi 2010-07-27 18:09:39

+1

@sbi:它們在手冊頁中稱爲精確寬度整數。但是我提到了不正確的頭文件。它不是types.h,而是stdint.h。我正在糾正答案。 – 2010-07-27 18:17:35

0

我認爲在這種情況下,您不需要知道您的架構有多少位。如果你想優化你的代碼,只要儘可能小就使用變量。

+0

鑑於問題的最後一段,我認爲這是一條路。如果所有值都小於256,則使用'uint8_t'。當您的CPU將其複製到一個寄存器中時,它將根據需要對其進行簽名擴展以填充寄存器的其餘部分。對於使用小於寄存器大小的數字,您應該看不到性能損失。你最好的選擇是使用'stdint.h'中最小的數據類型來代表你所有的值。 – bta 2010-07-27 18:17:58

+0

也許,但我想無符號字符是最便攜的答案,只是因爲stdint.h是從C99,而不是在以前 – 2010-07-27 18:55:24

相關問題