++ i, i = i + 1 и i + = 1 эквивалентны в C / C ++? - PullRequest
0 голосов
/ 09 февраля 2020

Меня беспокоит вопрос о том, являются ли выражения ++i;, i = i + 1; и i += 1; на сто процентов эквивалентными друг другу, если i определено ранее.

  1. ++i; - i немедленно увеличивается в выражении на 1 в выражении, в отличие от i++;, когда увеличение выполняется на 1 после выражения.
  2. i = i + 1; - i мгновенно увеличивается на 1 внутри оператора.
  3. i += 1; - i немедленно увеличивается на 1 внутри оператора.

Есть ли * какие-либо различия между этими выражениями или они на 100% эквивалентны?

* "Любой" может относиться к синтаксису и семантике, но также к производительности и памяти. управление.

Ответы [ 2 ]

7 голосов
/ 09 февраля 2020

C

В C, i = i+1 и i += 1 не эквивалентны, если i является типом atomi c, потому что составное присваивание - чтение-изменение-запись работа с семантикой memory_order_seq_cst, согласно C 2018 6.5.16.2 3. Я также не могу сказать, что стандарт C полностью ясен в отношении семантики i = i+1 и i += 1 в отношении летучих объектов. В противном случае ++i, i = i+1 и i += 1 эквивалентны, учитывая, что i является просто идентификатором, а не заполнителем для любого более сложного выражения.

C ++

In 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;
}

производит такой вывод:

Preincrement.
Addition.
Assignment.
AdditionAssignment.

, таким образом показывая, что для разных операций могут быть получены разные результаты.

Для фундаментальных типов операции могут быть в значительной степени эквивалентны, но я не квалифицирован, чтобы говорить с семантикой C ++ в отношении atomi c или volatile.

4 голосов
/ 09 февраля 2020

In 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 имеет тип atomi c, составное присваивание является операцией чтения-изменения-записи с семантикой порядка памяти memory_order_seq_cst.

Вы можете ожидать, что производительность будет чуть лучше для ++i, учитывая, что i оценивается только один раз в этом выражении, но это действительно сводится к деталям реализации и к тому, насколько хорошо ваш компилятор оптимизирует. Проблемы производительности и управления памятью не входят в компетенцию tag.

...