RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 994872
Accepted
Qwertiy
Qwertiy
Asked:2020-06-21 00:14:42 +0000 UTC2020-06-21 00:14:42 +0000 UTC 2020-06-21 00:14:42 +0000 UTC

使用 --x++ 有效吗?

  • 772

关于记录的可接受性和正确性有几个问题,例如--x++

  1. 说什么(--x)++是等价的是否正确(x-1)?也就是说,这段代码是否正确并且不会产生未定义的行为?

  2. 为什么必须在减量周围加上括号?我预计如果没有括号,构造中的编译器--x++将首先采用前缀操作,然后是后缀操作,但由于某种原因,它会做相反的事情:

    error: lvalue required as decrement operand
       cout << --x++ << endl;
                 ^~
    

    这个编译器行为正确吗?

程序示例:https ://ideone.com/q0Wu6U

#include <iostream>

using namespace std;

int main()
{
  int x = 8;
  cout << (--x)++ << endl;
  cout << x << endl;
  return 0;
}
c++
  • 4 4 个回答
  • 10 Views

4 个回答

  • Voted
  1. Best Answer
    AnT stands with Russia
    2020-06-21T00:46:28Z2020-06-21T00:46:28Z
    1. 根据定义,表达式的(--x)++行为类似于(x = x - 1)++. 从 C++17 开始,赋值运算符的求值过程是非常严格的:右侧完全排在左侧之前,赋值行为本身排在赋值结果求值之前操作员。

      即a = bC++ 17中计算赋值运算符的过程被划分为相互隔离的“隔间” [[a] = [b]],从右到左处理

      • 首先,评估值b并在b

      • 然后计算该值a并在a

      • 然后进行实际分配。

      • 并且只有在这之后,表达式的结果才会a = b返回到更高级别的上下文中
         

      这意味着不存在(--x)++未定义行为的情况。所有副作用和值读取都严格相对于彼此排序。该表达式不改变 的值x,其结果是原始值x减去1。

      在 C++14 及更早版本中,情况可能会有所不同……例如,在 C++17 之前,一个表达式会i = i++产生未定义的行为,但从 C++17 开始,该表达式的行为已经完全定义。但是,在您的具体示例中,C++11 中的一切都很好。形式上,行为在 C++98 中没有定义,但即使这样也被认为是 C++98 标准中的缺陷。

      值得注意的是,尽管 C++17 在评估单个赋值运算符的过程中引入了相当严格的顺序,但上述“隔间”并不能保证评估多个独立赋值运算符的过程彼此隔离。该表达式(i = 1) + (i = 2)仍然会产生未定义的行为,因为副作用i = 1相对于副作用没有排序i = 2。

    2. 在 C 和 C++ 中,无论年龄大小,后缀运算符都优先于前缀运算符。所以我不清楚你为什么期望什么--x++可能是一个有效的表达。

    • 8
  2. AR Hovsepyan
    2020-06-21T00:27:50Z2020-06-21T00:27:50Z

    看到 operator后,--编译器需要一个对象,并且由于它x++ 返回一个临时对象,因此该操作变得无效。有了括号,这个问题就消失了:先是减少对象的值,然后对同一个对象执行算子++

    关于第一个问题:我没有看到任何不正确的地方,也没有理由出现未定义的行为...... PS 此类表达式中的未定义行为是 --x + x-- 由于标准没有定义计算操作数的顺序(什么先评估--x还是x--?)在问题的情况下,这个问题没有。

    • 0
  3. Cerbo
    2020-06-21T00:57:04Z2020-06-21T00:57:04Z

    会有未定义的行为,你在同一个序列点有两个变化。括号不会创建一个点。

    • 0
  4. Дмитрий Зиненко
    2020-06-21T00:43:23Z2020-06-21T00:43:23Z

    1) 操作优先级: http://cppstudio.com/post/302/ 先后缀,后前缀。2) 后缀自增返回对临时对象(右值)的引用,而前缀自减只接受对永久对象(左值)的引用。3) 这里没有什么可以产生未定义的行为。--x 返回左值(对 x 的引用),(--x)++ 返回右值 - ((--x) 的副本)+ 1。右值对象的输出操作有效。此外,如果启用优化,它将直接用 x-1 替换此代码:

    int square(int num) {
        return (--num)++;
    }
    

    gcc9.1 -O2

    leal    -1(%rdi), %eax
    ret
    

    https://godbolt.org/z/rq1uA-

    • -1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5