Re[5]: operator int
От: B0FEE664  
Дата: 26.05.25 19:28
Оценка: +1
Здравствуйте, rg45, Вы писали:

M>>Тогда компилятор будет выбирать операторы в зависимости от порядка вычислений в выражениях, если ему нужно будет сложить два инта то он сложит два инта. И насколько я знаю, поправьте меня знатоки стандарта, этот порядок не всегда определен. Например, x = v + u + z — хз в каком порядке будет вычислено в итоге.


R>Тут важно не путать порядок выполнения операций и порядок вычисления значений операндов. Порядок выполнения операций определяется их приоритетами и ассоциативностью и строго определён: https://en.cppreference.com/w/cpp/language/operator_precedence. Совсем другое дело — порядок вычисления операндов (подвыражений) — он может быть любым (unspecified): https://en.cppreference.com/w/cpp/language/eval_order.html.


R>Например, в выражении foo(a) + bar(b) * baz(c) однозначно сначала выполнится умножение, потом сложение. А вот в каком порядке будут вызваны функции foo, bar, baz — это как решит компилятор.


Так, но не совсем так.

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

Для выражения x = v + u + z можно подобрать такие v + u + z, что в зависимости от порядка выполнения операций промежуточный результат может как оставаться в пределах или же выходить за пределы. В стандарте есть разъяснения по этому поводу.
  разъяснения

5 [Note 4 : The implementation can regroup operators according to the usual mathematical rules only where the
operators really are associative or commutative.41 For example, in the following fragment
int a, b;
/* ... */
a = a + 32760 + b + 5;
the expression statement behaves exactly the same as
a = (((a + 32760) + b) + 5);
due to the associativity and precedence of these operators. Thus, the result of the sum (a + 32760) is next added to
b, and that result is then added to 5 which results in the value assigned to a. On a machine in which overflows produce
an exception and in which the range of values representable by an int is [-32768, +32767], the implementation cannot
rewrite this expression as
a = ((a + b) + 32765);
since if the values for a and b were, respectively, −32754 and −15, the sum a + b would produce an exception while
the original expression would not; nor can the expression be rewritten as either
a = ((a + 32765) + b);
or
a = (a + (b + 32765));
since the values for a and b might have been, respectively, 4 and −8 or −17 and 12. However on a machine in which
overflows do not produce an exception and in which the results of overflows are reversible, the above expression
statement can be rewritten by the implementation in any of the above ways because the same result will occur. —end
note]


Вывод: порядок зависит от архитектуры.

Отдельно, по теме, стоить заметить, что

41) Overloaded operators are never assumed to be associative or commutative.

А раз у Marty есть свои операторы, то они запрещают компилятору менять порядок. Казалось бы. На самом деле компилятор может менять порядок как ему заблагорассудится до тех пор, пока результат остаётся таким, как если бы порядок не менялся.
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.