1

通过强制转换修复下面的警告是否安全,或者我可以简单地更改原型以返回 au_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;
}

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

4

3 回答 3

2

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

一般来说,您的代码看起来有点吓人,因为它似乎硬编码了基于 ASCII 值的字符假设。这不是我建议做的事情,请查看 isprint()功能和朋友以获取检查字符的便携方式。并且文本通常被假定为const char *,而不是const unsigned char *

最后,当然返回指向 static缓冲区的指针也可能有点危险,代码不是线程安全的,如果进行了多次调用,很难在外部跟踪返回值并意识到它何时被后续调用覆盖.

于 2012-09-24T07:55:32.913 回答
1

由于您的函数将 aunsigned char*作为输入,因此返回输出似乎是合理的unsigned char*,除非该函数的部分预期目的是从 转换unsigned charchar。如果这是目的的一部分,那么retval应该是一个数组char,而不是一个数组u_char

unsigned charto转换char可能对 2 的补码实现(几乎全部)是无操作的。但它实际上并不能保证,即使是 2 的补码。对于大于CHAR_MAX(通常为 127)的值,允许转换以更改位模式甚至引发信号。在从unsigned charto转换char 不是无操作(几乎没有)的实现中,从unsigned char*to 转换char*是不安全的,因此会发出警告。

所以实际上,警告告诉您需要决定(并记录)您的函数正在处理的字符类型。不要通过强制转换来避免该决定。

于 2012-09-24T08:11:45.917 回答
0

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

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

于 2012-09-24T08:57:25.003 回答