2011-08-10 87 views
4

我有這需要一個uint8_t *的函數參數:投無符號字符*(uint8_t *)爲const char *

uint8_t* ihex_decode(uint8_t *in, size_t len, uint8_t *out) 
{ 
    uint8_t i, hn, ln; 

    for (i = 0; i < len; i+=2) { 
     hn = in[i] > '9' ? (in[i]|32) - 'a' + 10 : in[i] - '0'; 
     ln = in[i+1] > '9' ? (in[i+1]|32) - 'a' + 10 : in[i+1] - '0'; 

     out[i/2] = (hn << 4) | ln; 
    } 

    return out; 
} 

我用這個函數:

uint8_t data[SPM_PAGESIZE]; // SPM_PAGESIZE = 256 bytes 
uint8_t sysex_data[SPM_PAGESIZE/2]; 
ihex_decode(data, strlen(data), sysex_data); 

但在這情況下,我的編譯器(AVR-GCC)返回一個警告:

的main.c | 89 |警告:在通過的 'strlen的' 參數1指針目標的符號性不同/usr/include/string.h|399|note:預計「爲const char *」,但參數的類型爲「uint8_t *」

所以,我發現的類型轉換數據的VAR的解決方案:

ihex_decode(data, strlen((const char *)data), sysex_data); 

該警告消失,但我不知道此解決方案是否安全。

有沒有更好的方法?

感謝

+1

爲什麼你使用'uint8_t'作爲顯然是'char'的類型? –

+0

因爲我的程序在微控制器上運行。所以我不能有負面價值。 –

+3

這沒有任何意義。輸入數據似乎是ASCII十六進制,所以它自然是char。輸出數據當然會保持爲uint8_t。 –

回答

4

它是安全的。該錯誤與混合8位無符號整數和字符有關,如果僅使用char,則會對其進行簽名。

我明白了,不過,該函數接受uint8_t並做char ACTER運算,所以應該接受char S(或const char S,針對此事)。請注意,字符常量'c'的類型爲char,並且在ihex_decode內部的表達式中混合了有符號和無符號,因此必須小心避免溢出或負數被視爲大正數。

最後一個樣式註釋。由於in沒有修改,所以在參數中它應該讀取const uint8_t* in(或const char* in,如上)。另一個樣式錯誤(可能導致非常糟糕的錯誤)是您接受len作爲size_t,但聲明i循環變量爲uint8_t。如果字符串的長度超過255個字節會怎麼樣?

+2

字符可以是有符號或無符號的,即達到實現AFAIK。 –

+0

OK,@Rudy,加起來「在這種情況下」:) :) –

+1

你可以編輯它。 –

1

一切是非常量*可以安全地鑄造爲const *在C.它是保存。

+0

但是這個警告並不是要拋棄'const'限定符。 – cnicutar

+2

警告是關於從'uint8_t *'到'char *'的轉換 – dreamlax

+0

我回答的問題是:'我想知道這個解決方案是否安全。'我回答了。 –

1

這是安全的。警告(我想)會彈出,因爲您正在從無符號轉換爲已簽名。

+0

我不完全確定它**是安全的。如果沒有後果,警告的目的是什麼? – dreamlax

+0

不是因爲strlen()期望** const ** char *? –

+0

@Loïc:不,它不是。 –

0

它的安全,字符的範圍< uint8_t。

相關問題