Чему будет равно i после
int i=5;или
++i++;
чему будет равно b:
int a = 5, b;
b = ++a + ++a;
Что удивительно, отвечают на эти вопросы чаще всего неверно. Я тоже в своё время попался на таком вопросе, что побудило меня серьезно заняться изучением матчасти.Правильный ответ в обоих случаях один и тот же - неизвестно. То есть компилятор что-то выдаст, но предугадать, что же случится - невозможно. Все дело в точках следования или Sequence points.
Как известно, точки следования представляют собой такие ситуации, когда состояние исполняемого кода соответствует состоянию абстрактной машины, которая описана стандартом языка C++.
Обратимся к этому замечателному документу:
Standard for Programming Language C++, Chapter 1At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.
Точки следования возникают в следующих ситуациях:
В интервалах между точками следования компилятор, соответствующий Стандарту, может выполнять (и часто выполняет) любые оптимизации кода, перегруппировывать выражения, изменять порядок их вычисления, если это не меняет исходной семантики кода. При выполнении кода могут быть побочные действия, влияние которых закончится только по достижению очередной точки следования.Standard for Programming Language C++, Chapter 115 There is a sequence point at the completion of evaluation of each full-expression.
16 When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all
function arguments (if any) which takes place before execution of any expressions or statements in the function body. There is also a sequence point after the copying of a returned value and before the execution of any expressions outside
the function13). Several contexts in C++ cause evaluation of a function call, even though no corresponding function call
syntax appears in the translation unit. [ Example: evaluation of a new expression invokes one or more allocation and
constructor functions; see 5.3.4. For another example, invocation of a conversion function (12.3.2) can arise in contexts
in which no function call syntax appears. -end example ] The sequence points at function-entry and function-exit
(as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the
function might be.
17 In the evaluation of each of the expressions
a && b
a || b
a ? b : c
a , b
using the built-in meaning of the operators in these expressions (5.14, 5.15, 5.16, 5.18), there is a sequence point after
the evaluation of the first expression14).
Вот что говорит Стандарт о вычислениях между точками следования:
Т.е. любое выражение, изменяющее скалярный объект несколько раз или считывающее его значение после изменения в промежутке времени от одной точки следования к другой при вычислениях приводит к неопределенному поведению или undefined behavior.Standard for Programming Language C++, Chapter 5Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions,
and the order in which side effects take place, is unspecified. Between the previous and next sequence point a
scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior
value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for
each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.
[ Example:
i = v[i ++]; / / the behavior is undefined
i = 7 , i++ , i ++; / / i becomes 9
i = ++ i + 1; / / the behavior is undefined
i = i + 1; / / the value of i is incremented
-end example ]
Таким образом, к примеру, вот здесь
b = ++a + ++а;
Комментариев нет:
Отправить комментарий