Ответ 1
Это неуказанное поведение, len_ = len
неопределенно упорядочено относительно выполнения тела buffer()
, что означает, что один будет выполняться перед другим, но не указывается, какой порядок, но есть заказ, поэтому оценки не могут перекрываться, поэтому поведение undefined. Это означает, что gcc
, clang
и Visual Studio
все правильно. С другой стороны, нецелесообразные оценки допускают перекрывающиеся оценки, которые могут привести к поведению undefined, как указано ниже.
Из черновик стандартного С++ 11 1.9
[intro.execution]:
[...] Каждая оценка в вызывающей функции (включая другие вызовы функций), которая иначе не является секвенированные до или после выполнения тела вызываемой функции, неопределенно секвенированы с в отношении выполнения вызываемой функции .9 [...]
и неопределенно секвенированный немного закроется до этого и говорит:
[...] Оценки A и B неопределенно секвенированы, когда либо A секвенируется до того, как B или B секвенированы до A, но не указано, что. [Примечание: неопределенно секвенированные оценки не могут пересекаться, но либо могут быть выполнены в первую очередь. -end note]
который отличается от неощутимых оценок:
[...] Если A не секвенирован раньше B и B не секвенированы до A, тогда A и B не подвержены влиянию. [Примечание: Выполнение непересекающихся оценки могут перекрываться. -end note] [...]
что может привести к поведению undefined (внимание мое):
За исключением случаев, когда отмечено, оценки операндов отдельных операторов и подвыражений отдельных выражения не подвержены влиянию. [Примечание: в выражении, которое оценивается более одного раза во время выполнения программы, необнаружированные и неопределенно упорядоченные оценки ее подвыражений не должны быть последовательно выполнялись в разных оценках. -end note] Вычисления значений операндов оператор упорядочивается перед вычислением значения результата оператора. Если побочный эффект скаляра объект не влияет на какой-либо другой побочный эффект на один и тот же скалярный объект или вычисление значения используя значение одного и того же скалярного объекта, поведение undefined [...]
Pre С++ 11
Pre С++ 11 порядок оценки подвыражений также не указан, но он использует точки последовательности в отличие от упорядочения. В этом случае есть точка последовательности при входе функции и выходе функции, которая гарантирует, что поведение undefined отсутствует. Из раздела 1.9
:
[...] Точки последовательности при вводе функции и выходе функции (как описано выше) являются функциями вызовов функций, которые оцениваются, независимо от синтаксиса выражения, которое вызывает функция может быть.
Отклонение порядка оценки
Различные варианты, сделанные каждым компилятором, могут казаться неинтуитивными в зависимости от вашей перспективы и ожиданий. Вопрос о прибивании порядка оценки является предметом EWG issue 158: N4228 Оценка оценки экспансии для Idiomatic С++, который рассматривается для С++ 17, но кажется противоречивым на основе реакции на опрос по этому вопросу. В этом документе рассматривается более сложный случай из 4-го издания "Язык программирования С++" . Который показывает, что даже те, у кого большой опыт работы на С++, могут сработаться.