Ответ 1
Позвольте мне попробовать интерпретировать стандарт С++ 11. В §1.9/15 говорится:
За исключением тех случаев, когда отмечено, оценки операндов отдельных операторов и подвыражений отдельных выражений не имеют никакого значения. [...] Если побочный эффект скалярного объекта не влияет на какой-либо другой побочный эффект на один и тот же скалярный объект или вычисление значения, используя значение одного и того же скалярного объекта, поведение undefined.
Конечно, int
является скалярным типом, а t.set(i).print(i + 5);
содержит побочный эффект на i
в set()
и вычисление значения i + 5
, поэтому, если не указано иное, поведение действительно undefined. Чтение §5.2.5 ( "Доступ к члену класса" ), я не мог найти никаких заметок о последовательностях относительно оператора .
. [Но см. Править ниже!]
Обратите внимание, что, конечно, гарантируется, что set()
выполняется до print()
, потому что последний получает возвращаемое значение первого как (неявный this
) аргумент.
Суть здесь заключается в том, что вычисление значения для аргументов print
является unsequenced неопределенно упорядоченным относительно вызова set
.
EDIT: после прочтения ответа в комментарии (@Xeno's), я перечитаю абзац в стандарте, и на самом деле он позже говорит:
Каждая оценка в вызывающей функции (включая другие вызовы функций), которая иначе не секретируется отдельно до или после выполнения тела вызываемой функции, неопределенно упорядочена относительно выполнения вызываемой функции.
Поскольку неопределенное упорядочение не является несущественным ( "выполнение нецелевых оценок может перекрываться", §1.9/13), это действительно не поведение undefined, а "просто" неуказанное поведение, а это означает, что и 15, и 5 являются правильными выводами.
Поэтому, когда <
означает "секвенирован раньше" и ~
означает "неопределенно упорядоченный", мы имеем:
(value computations for print() arguments ~ execution of set()) < execution of print()