保存有符号整数结果的变量是否会溢出(后递增的副作用),并且此后从未在任何表达式中使用过它,会导致 UB 吗?

问题描述 投票:0回答:1

考虑这个计划

#include <limits.h>

int main (void) {
    int i = 0;

    // Assume, user is a fair person, following the instruction strictly..
    printf ("Enter a number in the range [0 - INT_MAX] : \n"); 
    scanf ("%d", &i);

    while (i++ < INT_MAX) {
        // do some stuff..
        // value of variable i not used in loop body
    }

    // value of variable i is not used anywhere after loop body

    return 0;
}

在循环条件

i++ < INT_MAX
的最后一次计算中,表达式中
i
的值将为
INT_MAX
,但
i
将保存
INT_MAX + 1
的结果(后增量的副作用),即本质上是有符号整数溢出。循环条件
(INT_MAX < INT_MAX)
结果为
false
并且循环退出。变量
i
的值在循环体之后的程序中没有使用,但是,当然,一旦循环退出,它就会保存
INT_MAX + 1
的结果。

该程序是否具有未定义的行为?

PS:

  • 我搜索了一下并发现了几个相关的问题,但它们并不完全相同:

由于内存损坏而导致整数溢出导致未定义行为

如果表达式的中间结果溢出,则为未定义行为

在上述两个问题中,导致溢出的变量/表达式的值都以某种方式使用。

  • 我的问题非常具体,指向未定义的行为,我不是在寻找任何其他方法来执行示例程序中显示的内容。我很清楚如何避免 UB。

  • 如果您在帖子中包含来自语言标准的引用(如果有)、支持该行为(无论是否是 UB),我将不胜感激。

c integer-overflow post-increment
1个回答
0
投票

您似乎有一种错误的印象,即未定义的行为意味着您的程序将以您可能意想不到的方式运行。不是这个意思。

当程序包含未定义的行为时,C 标准不保证该程序将执行的操作。它可能会崩溃,可能会产生意想不到的结果,或者可能看起来工作正常。

正如您从最初的研究中了解到的那样,有符号整数溢出确实是未定义的行为。无论您随后是否尝试使用

i
都没有关系。你的程序仍然有未定义的行为。

无论您是否可能在这个特定实例中看到任何异常行为,可能不会,但同样无法保证这一点。

© www.soinside.com 2019 - 2024. All rights reserved.