2

好的,所以 fgetc() 返回一个 unsigned char 强制转换为 int,并且 EOF 在... EOF。如果您尝试将配置文件读入 char 数组,并且您的实现的 char 已签名,该怎么办?C99 的标准说,不仅结果实现定义为将不可表示的值分配给有符号变量,而且实现也可以选择引发信号!

6.3.1.3 有符号和无符号整数

当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则保持不变。

否则,如果新类型是无符号的,则通过在新类型中可以表示的最大值重复加或减一来转换值,直到该值在新类型的范围内。49)

否则,新类型是有符号的,值不能在其中表示;结果是实现定义的,或者引发了实现定义的信号。

像这样的结构很常见:

int c, i = 0;
char arr[1024];

for (; (c = getc(Descriptor)) != EOF && i < sizeof arr - 1; ++i)
{
        arr[i] = (char)c;
}
arr[i] = '\0';

如果 char 已签名并且 c 中的值高于可以表示的值,则执行强制转换也是实现定义的。

我发现我极不可能找到多年来成千上万的程序员遗漏的问题,尤其是在上述构造无处不在的情况下。

似乎通过这种方式读取的非文本代码可能会导致问题,因为某些字节可能具有不适合有符号字符的值。我从来没有见过真正解决这个投入使用的上述结构的修改版本。

我是否真的发现了与 C 标准相关的缺陷,或者注意到成千上万的其他程序员在他们的错误检查中没有并且未能实现?

4

0 回答 0