операторы — Почему выражение a = a + b — (b = a) дает предупреждение о точке последовательности в c ++?

Ниже приведен тестовый код:

int main()
{
int a = 3;
int b = 4;
a = a + b - (b = a);

cout << "a :" << a << " " << "b :" << b << "\n";
return 0;
}

Компиляция этого дает следующее предупреждение:

> $ g++ -Wall -o test test.cpp test.cpp: In function ‘int main()’:
> test.cpp:11:21: warning: operation on ‘b’ may be undefined
> [-Wsequence-point]

Почему операция может быть неопределенной?

Согласно моему пониманию, сначала подвыражение (b = a) должен оцениваться из-за более высокого приоритета (), поэтому установка b = a. Тогда, поскольку «+» и «-» имеют одинаковый приоритет, выражение будет оцениваться левоассоциативно. Таким образом, a + b следует оценить следующий, и, наконец, результат (b = a) следует вычесть из a + b, Я не вижу ни одного правило точки последовательности нарушается здесь.

20

Решение

Есть разница между выражением оценивали и завершение его побочные эффекты.

b = a Выражение присваивания будет оцениваться перед вычитанием из-за более высокого приоритета в скобках. Это обеспечит ценность a в результате оценки. Запись этого значения в bоднако может не завершиться до следующей точки последовательности, которая в этом случае является концом полного выражения. Поэтому конечный результат всего выражения не определен, поскольку вычитание может принимать значение b до или после назначения.

20

Другие решения

В C ++ подвыражения в арифметических выражениях не имеют временного упорядочения.

a = x + y;

Является x оценивается первым или y? Компилятор может выбрать либо, либо он может выбрать что-то совершенно другое. Порядок оценки не то же самое, что и приоритет оператора: приоритет оператора строго определен, а порядок вычисления определяется только для степени детализации, в которой ваша программа имеет точки последовательности.

Фактически, на некоторых архитектурах возможно испускать код, который оценивает как x а также y в то же время — например, архитектуры VLIW.

8

Чтобы решить это, разделите их на два разных утверждения.

PS: не забывайте, что люди могут совершать ошибки при выполнении арифметических операций. Поэтому лучше сделать операции более понятными, разделяя их в разных выражениях. Я надеюсь, что помог.

int main()
{
int a = 3;
int b = 4;

/* Two different Statements*/
b = a;

/* or a = a + b - a */
a = a + b - b;

cout<<"a :"<<a<<" "<<"b :"<<b<<"\n";
return 0;
}
-1

a = b + a - a;
просто написано как

a = b + a - (b = a)—— >> (опыт 1)

Следующие три результата такие же как (exp 1)
a = (b + a - (b = a));
a = ((b + a) - (b = a));
a = (b + a) - (b = a);

наблюдения
+, — операторы имеют такой же приоритет, а также ассоциативность слева направо
Следовательно, сначала выполняется «b + a», а затем перед вычитанием «a» присваивается значение «b».

Теперь соблюдайте следующее
Когда а = 10 и б = 20;

a = (b = a) - b + a; =======> a = 10; б = 10
a = ((b = a) - b + a); =======> a = 10; б = 10

a = ((b = a) - (b + a)); =======> a = -10; б = 10
Из приведенных выше выражений ясно, что даже если сначала выполняется внутренняя скобка, сначала следует ассоциативность, а затем приоритет

Замечания:
Чтобы избежать путаницы между приоритетом внешней и внутренней скобки
Рассмотрим следующее выражение
a = (b + a - (b = a)) =====> Фактический результат => a = 20, b = 10;
было бы а = 10, б = 10; (если приоритет является основным по сравнению с ассоциативностью)
Таким образом, в приведенном выше примере мы можем сказать, что ассоциативность является первичной по сравнению с предшествованием

-1
По вопросам рекламы [email protected]