Здравствуйте, Lorenzo_LAMAS, Вы писали:
А>>(Должен сказать, что в этом вопросе я несколько радикальнее Павла. По моему мнению, например, в следующем примере — UB:
А>>А>> i = (++i, 0);
А>>
А>>Павел, если я все правильно помню, с этим согласен не был.)
L_L>А не могли бы Вы объяснить в чем тут, по Вашему мнению, дело? Т.е. Вы считаете, что все-таки между двумя точками следования i модифицируется дважды благодаря ++ и присваиванию и несмотря на точку следования после ',' ?
Да. Пронумеруем для наглядности точки следования.
i = (++i, 0) ;
^ ^ ^
1 2 3
1 — где-то перед полным выражением; 2 — ее образует оператор запятая; 3 — в конце полного выражения.
У нас есть так же два побочных эффекта: присваивание и инкремент. Мы можем утверждать, что побочный эффект инкремента должен произойти между точками следования 1 и 2. Но о побочном эффекте присваивания мы можем сказать лишь, что он должен произойти между точками следования 1 и 3. Ни из чего в стандарте не следует, что побочный эффект присваивания должен происходить после всех побочных эффектов подвыражения в правой части.
Иначе. Этот пример можно рассматривать следующим образом.
i = A;
где подвыражение A модифицирует переменную i. Точек следования в полном выражении нет. Переменная i модифицируется более одного раза между двумя соседними точками следования (1 и 3).
P.S. В
этом документе дается более подробное и лучше формализованное, чем в стандартах C/C++, описание точек следования. (В нем, в частности, рассматриваемый пример имеет well-defined behavior.) Но документ этот так и не стал нормативным ни для C, ни для C++.