将char / unsigned char转换为安全吗?

时间:2012-09-24 07:54:33

标签: c

使用强制转换修复下面的警告是否安全,或者我可以简单地更改原型以返回u_char吗?

  

警告:从结果类型为'char *'的函数返回'u_char [256]'将指针转换为具有不同符号的整数类型[-Wpointer-sign]

char   * whatever(unsigned char *text)
{
        static u_char retval[256];
        int pos = 0;

        *retval = 0;
        if (!text)
                return retval;

        for (; *text && (pos < 254); text++, pos++) {
                if (*text < 32) {
                        retval[pos++] = '^';
                        retval[pos] = *text + 64;
                } else if (*text == 127) {
                        retval[pos++] = '^';
                        retval[pos] = '?';
                } else
                        retval[pos] = *text;
        }

        retval[pos] = 0;
        return retval;
}

我也对其他可能性持开放态度。

3 个答案:

答案 0 :(得分:2)

当然,如果您认为数据是无符号的,则应更改返回类型。

一般来说,您的代码有点可怕,因为它似乎是基于ASCII值硬编码字符的假设。这不是我建议做的事情,请查看isprint()函数和朋友以便于检查字符的便携方式。通常假定文字为const char *,而不是const unsigned char *

最后,将指针返回到static缓冲区当然也有点危险,代码不是线程安全的,如果多次调用,则很难在外部跟踪返回值和意识到它被后续电话覆盖。

答案 1 :(得分:1)

由于您的函数对输入采用unsigned char*,因此为输出返回unsigned char*似乎是合理的,除非该函数的部分预期目的是从{{1转换到unsigned char。如果这是目的的一部分,那么char应该是retval的数组,而不是char的数组。

u_char转换为unsigned char可能是2的补码实现上的无操作(大约所有这些)。但实际上并没有保证,即使是2的补码。对于大于char(通常为127)的值,允许转换更改位模式甚至提升信号。在从CHAR_MAX转换为unsigned char 的实现不是无操作(大约没有)的情况下,从char转换为unsigned char*不安全,因此警告。

因此,实际上,警告告诉您需要决定(并记录)您的函数处理的字符类型。不要使用强制转换来避免该决定。

答案 2 :(得分:0)

有数百万行代码将char*unsigned char*视为可互换,而C标准并未强制要求它们可互换。这是否“安全”取决于你的意思...如果你认为你可能将你的代码移植到当前不存在的符合实现之一,它们是不可互换的,或者如果你订阅那些说不符合C标准的东西可能会消灭你的硬盘。

但是,编写正确的类型安全代码是更好的做法,在这种情况下甚至不会出现问题。换句话说,不要因为它是“不安全”而避免使用强制转换,因为这是一种糟糕的编码习惯。部分不好的是,任何演员阵容都可以隐藏一个错误...例如,假设你认为是char*你正在投射到unsigned char*的其他类型,比如说一个intint* ...你刚刚阻止编译器告诉你它。类型和类型安全是通过在编译时及早捕获它们来避免错误的强大工具。