2011-08-10 63 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。

相关问题