【问题标题】:Why does C++ accept multiple prefixes but not postfixes for a variable为什么 C++ 接受多个前缀但不接受变量的后缀
【发布时间】:2012-07-25 15:23:42
【问题描述】:

在调查Can you have a incrementor and a decrementor on the same variable in the same statement in c

我发现一个变量可以有多个前缀递增/递减运算符,但只有一个后缀

例如:

++--++foo; // valid
foo++--++; // invalid
--foo++;   // invalid

这是为什么?

【问题讨论】:

    标签: c++ increment prefix decrement postfix-operator


    【解决方案1】:

    在 C++ 语言中,前缀递增/递减运算符返回 lvalues,而后缀运算符返回 rvalues。同时,所有修改运算符都需要左值参数。这意味着前缀递增/递减的结果可以传递给任何其他需要左值参数的附加运算符(包括额外的递增/递减)。

    出于同样的原因,在 C++ 中您可以编写这样的代码

    int i = 0;
    int *p = &++i;
    

    这将增加i 并使p 指向i。一元 & 需要左值操作数,这就是为什么它将与前缀 ++ 的结果一起使用(但不适用于后缀之一)。

    将多个内置前缀递增/递减应用于同一对象的表达式会产生未定义的行为,但它们仍然是格式良好的(即“可编译”)。

    ++foo-- 这样的表达式是无效的,因为在 C++ 中后缀运算符的优先级高于前缀运算符。大括号可以改变这一点。例如,(++foo)-- 是一个格式良好的表达式,尽管它再次导致未定义的行为。

    【讨论】:

    • 您能否展示一些说明结果未定义的文档?在我看来,它应该是完全明确的(从右到左向外评估)。
    • @RichardJ.RossIII UB 因为 (C++11, 1.9p15) “如果一个标量对象的副作用相对于同一个标量对象的另一个副作用或值是无序的使用相同标量对象的值进行计算,行为未定义。”
    • @Richard J. Ross III:C++ 语言规范(C++98、C++03)中著名的第 5/4 段。在不干预 sequence point (SP) 的情况下两次修改同一个对象是非法的(在 UB 意义上)。 C++ 没有为没有 SP 的内置运算符定义求值顺序。没有 SP 的 C++ 中没有“从左到右求值”之类的东西。任何排序都需要干预 SP。 ++--foo 中没有序列点,因此行为未定义。 C++11 使用不同的形式化方法进行排序,但基本原理保持不变。
    【解决方案2】:

    这是因为在 C++(但不是 C)中,++x 的结果是一个 lValue,这意味着它是可赋值的,因此是可链接的。

    但是,x++ 的结果不是 lValue,而是 prValue,这意味着它不能被赋值,因此不能被链接。

    【讨论】:

      猜你喜欢
      • 2020-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 1970-01-01
      相关资源
      最近更新 更多