c - 设置为 CHAR_MAX 的字符值是否保证环绕到 CHAR_MIN?

标签 c char language-lawyer standards integer-overflow

我的代码:

#include <stdio.h>
#include <limits.h>

int main()
{
    char c = CHAR_MAX;
    c += 1;
    printf("CHAR_MIN=%d CHAR_MAX=%d c=%d (%c)\n", CHAR_MIN, CHAR_MAX, c, c);
}

输出:

CHAR_MIN=-128 CHAR_MAX=127 c=-128 ()

我们看到,当我们增加一个 char变量设置为 CHAR_MAX ,它环绕到 CHAR_MIN .这种行为有保证吗?或者它将是未定义的行为或实现指定的行为? C99 标准对此有何评论?

[注:What happen when give value bigger than CHAR_MAX (127) to charC- why char c=129 will convert into -127?没有解决这个问题,因为他们谈论分配一个超出范围的值而不是将一个值增加到一个超出范围的值。]

最佳答案

问题是双重的:首先,是

char c = CHAR_MAX;
c += 1;

评价不同
char c = CHAR_MAX;
c = c + 1;

答案是否定的,因为C11/C18 6.5.16.2p3 :

  1. A compound assignment of the form E1 op = E2 is equivalent to the simple assignment expression E1 = E1 op (E2) except that the lvalue E1 is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. If E1 has an atomic type, compound assignment is a read-modify-write operation with memory_order_seq_cst memory order semantics. 113)


那么,问题是在 c = c + 1 中发生了什么.这里的操作数为 +进行通常的算术转换,和 c1因此被提升为 int ,除非一个非常古怪的架构需要 char晋升为 unsigned int . +的计算然后计算结果,类型为 int/unsigned int转换回 char并存储在 c .

3 然后可以评估实现定义的方法:
  • CHAR_MIN是 0,因此 char未签名。

    要么char然后被提升为 intunsigned int如果它被提升为 int ,然后 CHAR_MAX + 1必然适合 int也不会溢出,或者如果unsigned int它可能适合或环绕为零。当结果值,即在数字上是 CHAR_MAX + 10取模后,回到 c , 取模后变为 0, 即 CHAR_MIN
  • 否则 char已签名,则如果 CHAR_MAX小于 INT_MAX , CHAR_MAX + 1 的结果将适合 int , 和标准 C11/C18 6.3.1.3p3适用于赋值时发生的转换:

    1. Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
  • 或者,伊夫 sizeof (int) == 1 char签名,然后 char被提升为 int , 和 CHAR_MAX == INT_MAX => CHAR_MAX + 1将导致整数溢出和 行为将是未定义的 .

  • IE。可能的结果是:
  • char是无符号整数类型,结果总是0 ,即 CHAR_MIN .
  • 否则 char是有符号整数类型,行为是实现定义的/未定义的:
  • CHAR_MIN或其他一些实现定义的值,
  • 引发了一个实现定义的信号,可能会终止程序,
  • 或者行为在某些平台上未定义 sizeof (char) == sizeof (int) .


  • 所有增量操作 c = c + 1 , c += 1 , c++++c在同一平台上有相同的副作用。表达式 c++ 的计算值将是 c 的值增量前;对于其他三个,它将是 c 的值增量后。

    关于c - 设置为 CHAR_MAX 的字符值是否保证环绕到 CHAR_MIN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60586881/

    相关文章:

    C - 用单个字符替换连续多次出现的字符

    c++ - std::copy_exception 在哪里定义?

    c++ - 为什么 bitand 没有正确解析以形成右值引用?

    c++ - 类模板中声明的友元函数的模板参数推导

    c - 将文件字符串转换为字符指针

    c - 关于 Makefile 中的 CFLAGS

    c - 从不兼容指针类型进行赋值以及取消引用指针到不完整类型

    c - 如何通过套接字发送 XDR 结构内的数组

    c - 在 C 程序中使用 0 而不是 '\0'

    java - 如何用Java中的空格替换字符串中的奇数/偶数字符?