Здравствуйте, Аноним, Вы писали:
А>int u = 0; А>(++u,u++,++u) = u;
А>правильно ли то, что выражение (++u,u++,++u) будет вычислено до оператора = ?
Здесь имеет место неопределенное поведение именно из-за того, что в правой части оператора присваивания у вас находится та же самая переменная.
Что касается левой части, то тут все просто и после каждой запятой имеет место быть точка последовательности вычисления выражений. То есть в правой части на выходе вы получите значение равное 3. Проблема возникает из-за того, что непонятно, а что должно быть в правой части выражения. То есть все зависит от порядка вычислений выражений в правой и левой части.
Здравствуйте, night beast, Вы писали:
NB>будет ли UB: ++u = u; NB>да, будет.
Я даже больше скажу
А=Б;
наблюдал что вычислилось сначала l-value А со своим side-efect а потом Б ( а может так и положено ). Могу ошибаться но кажется с++11 внес какието коррективы в трехместные операторы, хотя у Микрософт в этом месте заявлено UB. Вообщем — пишите без side-efect-ов.
Здравствуйте, Programador, Вы писали:
P>Я даже больше скажу P>А=Б; P>наблюдал что вычислилось сначала l-value А со своим side-efect а потом Б ( а может так и положено ).
порядок вычисления не специфицирован, поэтому ничего удивительного в этом нет.
P>Могу ошибаться но кажется с++11 внес какието коррективы в трехместные операторы, хотя у Микрософт в этом месте заявлено UB. Вообщем — пишите без side-efect-ов.
насколько знаю, изменилась формулировка (убрали понятие sequence point)
но смысл не изменился.
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, Ops, Вы писали:
Ops>>Мордобой тут будет. V>Щас придёт кодт и удалит твоё сообщение за экстремизм обсуждение профессионализма участников.
Ненуаче? Человек пишет абсолютно провокационный пост...
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Masterkent, Вы писали:
M>night beast:
NB>>насколько знаю, изменилась формулировка (убрали понятие sequence point) NB>>но смысл не изменился.
M>В C++11 меньше ограничений. Например, в C++11 можно делать так:
M>
(x *= y) += z;
M>где x имеет арифметический тип.
Абсолютно то же самое можно делать и в С++ 2003. Я не вижу, что изменилось? Значением составного оператора присваивания является lvalue. Так что написано совершенно корректное выражение с точки зрения стандарта С++ 2003.
Сыроежка: NB>>>насколько знаю, изменилась формулировка (убрали понятие sequence point) NB>>>но смысл не изменился. M>>В C++11 меньше ограничений. Например, в C++11 можно делать так: M>>
(x *= y) += z;
M>>где x имеет арифметический тип. С>Абсолютно то же самое можно делать и в С++ 2003.
Будет undefined behavior согласно 5/4:
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.
Операторы *= и += не вводят никаких точек следования. С>Я не вижу, что изменилось?
Усовершенствована модель упорядочивания вычислений — см.
1.9 Program execution
13 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread (1.10), which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced evaluations can overlap. —end note ] Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [ Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first. —end note ]
14 Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated. [Footnote: As specified in 12.2, after a full-expression is evaluated, a sequence of zero or more invocations of destructor functions for temporary objects takes place, usually in reverse order of the construction of each temporary object.].
15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. —end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either anotherside effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
[ Example:
void f(int, int);
void g(int i, int* v) {
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
f(i = -1, i = -1); // the behavior is undefined
}
—end example ]
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. —end note ] Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function. [Footnote: In other words, function executions do not interleave with each other. ] 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 sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.
5.17 Assignment and compound assignment operators — p.1
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
В данном случае имеем строгий порядок:
вычисление значения x -> модификация x -> вычисление результирующего значения (x *= y) -> модификация x. Таким образом, условия возникновения undefined behavior (см. выделенное жирным) с точки зрения C++11 тут нет.
Здравствуйте, Masterkent, Вы писали: M>Сыроежка: NB>>>>насколько знаю, изменилась формулировка (убрали понятие sequence point) NB>>>>но смысл не изменился. M>>>В C++11 меньше ограничений. Например, в C++11 можно делать так: M>>>
(x *= y) += z;
M>>>где x имеет арифметический тип. С>>Абсолютно то же самое можно делать и в С++ 2003. M>Будет undefined behavior согласно 5/4: M>
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.
M>Операторы *= и += не вводят никаких точек следования. С>>Я не вижу, что изменилось? M>Усовершенствована модель упорядочивания вычислений — см. M>
1.9 Program execution
13 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread (1.10), which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced evaluations can overlap. —end note ] Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [ Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first. —end note ]
M>14 Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated. [Footnote: As specified in 12.2, after a full-expression is evaluated, a sequence of zero or more invocations of destructor functions for temporary objects takes place, usually in reverse order of the construction of each temporary object.].
M>15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. —end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either anotherside effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
M>[ Example:
M>
void f(int, int);
M>void g(int i, int* v) {
M> i = v[i++]; // the behavior is undefined
M> i = 7, i++, i++; // i becomes 9
M> i = i++ + 1; // the behavior is undefined
M> i = i + 1; // the value of i is incremented
M> f(i = -1, i = -1); // the behavior is undefined
M>}
M>—end example ]
M>When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. —end note ] Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function. [Footnote: In other words, function executions do not interleave with each other. ] 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 sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.
M>
5.17 Assignment and compound assignment operators — p.1
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
M>В данном случае имеем строгий порядок: M>вычисление значения x -> модификация x -> вычисление результирующего значения (x *= y) -> модификация x. Таким образом, условия возникновения undefined behavior (см. выделенное жирным) с точки зрения C++11 тут нет.
Вы что-то путаете, то есть, как говорится, слышали звон, да не знаете, где он. Причем здесь точки последовательности?! Более того, вы приводите примеры, которые к исходному примеру никакого отношения не имеют! Например, какое отношение ваш пример i = v[i++]; имеет к выражению (x *= y) += z;?!
В этом послднем выражение вообще ничего не зависит от порядка вычисления исходных переменных x, y и z. Но расставленные скобки имеют приоритет в выполнении операций. Поэтому данное выражение совершенно однозначно вычисляется. При этом не важно, вычислите вы сначала z или сначала x *= y. Результат вычисления всего выражения от этого не меняется. В левой части выражения у вас будет lvalue, которое является результатом выражения ( x *= y ) (видите круглые скобочки?!). А затем этому lvalue будет присвоего значение z и снова получите lvalue.
Следуя же вашей логике, получается, например, что выражение ( x + y ) / z имеет неопределенное поведение. С чего это, вдруг?! Или другой пример, (ведь можно убрать знак второй операции, не так ли?!) получается, что выражение ( x = y ) = z иаеет неопредленное значение соогласно вашему утверждению. На самом деле оно имеет четко определенное поведение и ( x = y ) = z отличается от x = ( y = z ). Оба этих выражений имеют корректное и определенное поведение.
Я уже обратил внимание, что вы лихо цитируете стандарт (дело нехитрое), но совершенно не понимаете, о чем в нем идет речь.
Здравствуйте, Masterkent, Вы писали: M>Сыроежка: NB>>>>насколько знаю, изменилась формулировка (убрали понятие sequence point) NB>>>>но смысл не изменился. M>>>В C++11 меньше ограничений. Например, в C++11 можно делать так: M>>>
(x *= y) += z;
M>>>где x имеет арифметический тип. С>>Абсолютно то же самое можно делать и в С++ 2003. M>Будет undefined behavior согласно 5/4: M>
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.
M>Операторы *= и += не вводят никаких точек следования. С>>Я не вижу, что изменилось? M>Усовершенствована модель упорядочивания вычислений — см. M>
1.9 Program execution
13 Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread (1.10), which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced evaluations can overlap. —end note ] Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which. [ Note: Indeterminately sequenced evaluations cannot overlap, but either could be executed first. —end note ]
M>14 Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated. [Footnote: As specified in 12.2, after a full-expression is evaluated, a sequence of zero or more invocations of destructor functions for temporary objects takes place, usually in reverse order of the construction of each temporary object.].
M>15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. —end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either anotherside effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
M>[ Example:
M>
void f(int, int);
M>void g(int i, int* v) {
M> i = v[i++]; // the behavior is undefined
M> i = 7, i++, i++; // i becomes 9
M> i = i++ + 1; // the behavior is undefined
M> i = i + 1; // the value of i is incremented
M> f(i = -1, i = -1); // the behavior is undefined
M>}
M>—end example ]
M>When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. —end note ] Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function. [Footnote: In other words, function executions do not interleave with each other. ] 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 sequencing constraints on the execution of the called function (as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the function might be.
M>
5.17 Assignment and compound assignment operators — p.1
In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.
M>В данном случае имеем строгий порядок: M>вычисление значения x -> модификация x -> вычисление результирующего значения (x *= y) -> модификация x. Таким образом, условия возникновения undefined behavior (см. выделенное жирным) с точки зрения C++11 тут нет.
Приношу свои извинения. Я погорячился в предыдущем ответе. Одновременно отвечал на другом форууме, а потому был не внимателен. Спасибо за инофрмацию.