3

我在 C 中有以下代码:

char input[127] = "hello world";

isxdigit(input[0]);

但我收到以下警告:

warning: array subscript has type 'char'

是什么原因以及如何解决?

4

3 回答 3

8

原因是在您的 C 实现中,isxdigit()是使用数组查找作为宏实现的。

只要您的输入字符串仅包含字符 <=127,您就可以使用强制转换来修复它:

isxdigit ((int)input[0]);

或者,如果您认为演员表丑陋,请借助良性表达,例如添加 0:

isxdigit (0 + input[0]);  /* Avoid cast by using an int-typed expression. */
isxdigit (+input[0]);     /* Same thing using unary plus instead of addition. */

由于 C 标准要求它isxdigit也是一个函数,因此您可以选择调用函数而不是宏:

(isxdigit)(input[0]);

甚至

#undef isxdigit
isxdigit(input[0]);

这应该不会产生警告,因为input[0]被提升为int(假设先验#include <ctype.h>。)

char正如 cmaster 正确指出的那样,一旦您签署并包含负值,这些解决方案就会崩溃。在这种情况下,您必须先转换为(如果需要unsigned char,再转换为)。int

于 2013-07-07T12:07:11.927 回答
2

原因是isxdigit有原型int isxdigit(int)。因此,要删除此警告,您应该将参数显式转换为int

isxdigit((int)input[0]);
于 2013-07-07T12:06:35.303 回答
2

关键是,标准没有定义 char 类型是否是有符号的,将这个决定留给实现。因此(int)(char)128可以评估为 128 或 -128。正如您的编译器所注意到的那样,后者显然对数组索引不利(聪明的家伙,那个编译器)。

所以正确的解决方法是强制转换为unsigned char,而不是int

isxdigit((unsigned char)input[0])

如果你选择其他错误的答案,你最终可能会在 utf8 字符串上崩溃!(utf8 对多字节字符使用大于 127 的代码。)

编辑:当然,Pascal Cuoq 说得对,不允许这样的实现将 isxdigit 实现为表查找宏,但是,我所说的适用于任何出现此编译器警告的情况,包括您实现的任何查找表你自己。非常不幸的是,char 的符号没有定义,人们应该更好地了解这个问题并知道如何正确地避免它。

于 2013-07-07T12:33:25.673 回答