【问题标题】:Does this post-increment statement result in undefined behaviour? [duplicate]这个后增量语句是否会导致未定义的行为? [复制]
【发布时间】:2018-10-26 03:03:28
【问题描述】:

在使用较新版本的 GCC 构建程序时,我发现代码中存在问题。

count[i] = count[i]++;

此代码适用于较旧版本的 GCC (2.95),但不适用于较新版本 (4.8)。

所以我怀疑这种说法会导致未定义的行为,对吗?或者这个问题有更好的术语吗?

【问题讨论】:

  • Gcc 是一个 C 编译器。您的问题是关于 C++ 还是 C?
  • @DYZ 好吧,“GCC”也可以是包含 C 编译器和 C++ 编译器以及许多其他内容的软件套件的名称...
  • 这个问题是关于 C++ 的,但是如果在这个问题上与 C 有什么不同,我也想知道。

标签: c++ undefined-behavior side-effects


【解决方案1】:

这实际上被指定为未定义的行为,因为每个编译器都定义了自己的操作顺序,如下所述:https://en.cppreference.com/w/cpp/language/eval_order

几乎所有 C++ 运算符的操作数的求值顺序(包括函数调用表达式中函数参数的求值顺序和任何表达式中子表达式的求值顺序)未指定。编译器可以按任何顺序计算操作数,并且在再次计算同一表达式时可能会选择其他顺序。

cppreference中的递增/递减页面其实有警告:https://en.cppreference.com/w/cpp/language/operator_incdec

由于涉及的副作用,必须小心使用内置的递增和递减运算符,以避免由于违反排序规则而导致的未定义行为。

【讨论】:

    【解决方案2】:

    确实,这是未定义的行为。

    int i = 2;
    i = i++; // is i assigned to be 2 or 3?
    

    【讨论】:

    • 根据运算符优先级,i++ 将首先被评估,然后是赋值,所以它会被赋值为 3.en.cppreference.com/w/c/language/operator_precedence 虽然这可能会因 std=而异
    • @awiebe 运算符优先级与order of evaluation 不同。在 C++17 之前,此代码是未定义的行为。
    • @awiebe 问题不在于何时评估i++,而是何时发生增量。如果增量发生在分配之后与增量发生在分配之前,结果将是不同的。增量不同于评估。这段代码将 2 和 3 都写入 i,并且不需要先写入(直到 C++ 17)。
    • @awiebe gcc 4.7.4 返回 i=3 而 gcc 4.8.1 返回 i=2。
    猜你喜欢
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 2019-09-26
    相关资源
    最近更新 更多