Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 铸造字符/未签名字符是否安全?_C - Fatal编程技术网

C 铸造字符/未签名字符是否安全?

C 铸造字符/未签名字符是否安全?,c,C,使用强制转换修复下面的警告是否安全,或者我可以简单地更改原型以返回u_char 警告:从结果类型为“char*”的函数返回“u_char[256]”时,指针之间会转换为具有不同符号[-Wpointer sign]的整数类型 char*任意字符(无符号字符*文本) { 静态u_字符检索[256]; int pos=0; *retval=0; 如果(!text) 返回返回; 对于(;*text&&(pos当然,如果您认为数据是未签名的,则应该更改返回类型。 一般来说,您的代码看起来有点吓人,因为它似

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

警告:从结果类型为“char*”的函数返回“u_char[256]”时,指针之间会转换为具有不同符号[-Wpointer sign]的整数类型

char*任意字符(无符号字符*文本)
{
静态u_字符检索[256];
int pos=0;
*retval=0;
如果(!text)
返回返回;
对于(;*text&&(pos<254);text++,pos++){
如果(*文本<32){
retval[pos++]='^';
retval[pos]=*文本+64;
}如果(*text==127),则为else{
retval[pos++]='^';
retval[pos]='?';
}否则
retval[pos]=*文本;
}
retval[pos]=0;
返回返回;
}

我也愿意接受其他的可能性

> P>当然,如果您认为数据是未签名的,则应该更改返回类型。

一般来说,您的代码看起来有点吓人,因为它似乎对基于ASCII值的字符的假设进行了硬编码。我不建议这样做,请查看
isprint()
函数和friends,了解检查字符的便携方法。文本通常被假定为
常量字符*
,而不是
常量无符号字符*


最后,返回指向
静态
缓冲区的指针当然也有点危险,代码不是线程安全的,如果执行了多个调用,则很难从外部跟踪返回值,并在它被后续调用覆盖时实现。

由于您的函数对输入采用了
无符号字符*
,因此它对输出返回
无符号字符*
似乎是合理的,除非函数的部分预期用途是将
无符号字符
转换为
字符
。如果这是目的的一部分,那么
retval
应该是
char
的数组,而不是
u_char
的数组

unsigned char
转换为
char
对于2的补码实现(几乎全部)来说可能是不可行的。但事实上,即使是在2的补码上,也不能保证是这样。对于大于CHAR_MAX(通常为127)的值,允许进行转换以改变位模式,甚至产生信号。在从
unsigned char
转换为
char
不是禁止操作的实现上(几乎没有),从
unsigned char*
转换为
char*
是不安全的,因此会发出警告


因此,实际上,警告告诉您需要决定(并记录)函数所处理的字符类型。不要用cast来避免这个决定。

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


但更好的做法是编写正确的类型安全代码,在这种情况下甚至不会出现问题。换句话说,不要因为强制转换“不安全”而避免它,要因为它是糟糕的编码实践而避免它。其中一个坏处是任何演员都可以隐藏一只虫子。。。例如,假设您认为要转换为
无符号字符*
char*
实际上是另一种类型,例如
int
int*
。。。您刚刚阻止编译器告诉您有关它的信息。类型和类型安全性是通过早期捕获来避免bug的强大工具。。。在编译时。

我敢说每个人都假设文本是
常量unsigned char*
。碰巧的是,对于许多人来说,如果手头的实现将
char
视为有符号类型而不是无符号类型,那么这种差异并不重要。
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;
}