Разница не в указателях, как вы подозревали вначале, но в другом порядке правил оценки. В «новой» 11 C++ «Sequenced-до того правила», мы имеем:
Побочный эффект (модификация левого аргумента) оператора присваивания встроенной и всех встроенных сложные вычисления присваиваются после вычисления значения (но не побочных эффектов) как левого, так и правого аргументов и секвенируются перед вычислением значения выражения присваивания (то есть перед возвратом ссылки на модифицированный объект)
(От cppr.) Это правило гарантирует желаемую оценку вашего выражения налево-вправо.
В отличие от этого, C и C++ 98 используют «Точки последовательности». Так как в длинном заявлении нет точек последовательности, у вас есть несколько неощутимых изменений значений, на которые указывают указатели, и, таким образом, вызывать Undefined Behavior.
Для C gcc предупреждает об этом (live). Для C++ 98 он, по-видимому, уже использует новые правила, что прекрасно, потому что неопределенное поведение не определено.
Разделение утверждения решает эту проблему, конечно, потому что конец инструкции явно вводит точки последовательности, в которых они вам нужны. Это также превосходно, потому что оно более читаемо и не нужно знать правила последовательности, чтобы определить, правильно ли код.
Для справки: Большое разъяснение правил секвенирования в C++ можно найти here.
** - 1 ** Я прекратил читать при «* x^= * y^= * x^= * y;". Если вы собираетесь задать вопрос, введите код, который менее отталкивает. Благодарю. –
@ Cheersandhth.-Alf Я боюсь, что эта отталкивающая линия - вот что вопрос в конце. –
Не знаете, почему downvotes? Вопрос содержит рабочий код, который воспроизводит ошибку.Это не так много вопросов. Он также представляет интересную разницу между 'C' и' C++', которые могут укусить других людей. Неужели мы действительно проголосовали за кодовое снобизм? – Galik