++i、i = i + 1 和 i += 1 在 C/C++ 中是否等效?

Are ++i, i = i + 1 and i += 1 equivalent in C/C++?

本文关键字:是否 C++ ++i      更新时间:2023-10-16

我真正关心的是,如果之前定义了i,那么++i;i = i + 1;i += 1;的表达式是否百分之百地等价。

  1. ++i;-i在语句中立即递增1,而不是在表达式之后按1递增i++;
  2. i = i + 1;- 语句中的i立即递增1
  3. i += 1;- 语句中的i立即递增1

这些表达式之间是否存在*任何差异,或者它们是 100% 等效的?

*"Any"可以指语法和语义,也可以指性能和内存管理。

C

在 C 中,如果i是原子类型,则i = i+1i += 1不等效,因为复合赋值是具有memory_order_seq_cst语义的读-修改-写操作,根据 C 2018 6.5.16.2 3。我也不能说 C 标准在易失性对象的i = i+1i += 1语义上是完全清楚的。否则,++ii = i+1i += 1是等价的,因为i只是一个标识符,而不是任何更复杂的表达式的占位符。

C++

在C++中,操作并不等效。证明:

此程序:

#include <iostream>

class SensitiveToOperations
{
public:
SensitiveToOperations operator ++() { std::cout << "Preincrement.n"; return *this; }
SensitiveToOperations operator +(int that) const { std::cout << "Addition.n"; return *this; }
SensitiveToOperations operator =(SensitiveToOperations that) { std::cout << "Assignment.n"; return *this; }
SensitiveToOperations operator +=(int that) { std::cout << "AdditionAssignment.n"; return *this; }
};

int main(void)
{
SensitiveToOperations i;
++i;
i = i + 1;
i += 1;
}

生成以下输出:

预递增。 加法。 分配。 附加分配。

从而表明对于不同的操作可以获得不同的结果。

对于基本类型,操作可能在很大程度上是等价的,但我没有资格谈论有关原子或易失性C++语义。

在 C 中,++i等价于(i += 1)

C11标准草案6.5.3.1p2:

表达式 ++E 等效于 (E+=1(。

表达式i += 1等价于i = i + 1只是在第一种情况下i保证只被计算一次。在函数调用中i += 1结果为单个计算。

C11标准草案6.5.16.2p3:

形式为 E1 op = E2 的复合赋值等效于 简单赋值表达式 E1 = E1 op (E2(,除了左值 E1 仅评估一次,并且相对于 不确定序列的函数调用,复合的操作 分配是单一评估。如果 E1 具有原子类型,则化合物 赋值是具有memory_order_seq_cst的读取-修改-写入操作 内存顺序语义。

您可能会期望++i的性能略好一些,因为在此表达式中只计算一次i,但这实际上归结为实现细节以及编译器的优化程度。性能和内存管理问题不在语言律师标记的范围之内。