Это unspecified behavior, len_ = len
является неопределенно секвенировали относительно исполнения тела buffer()
, что означает, что один будет выполняться до другого, но не указано, в каком порядке, но есть порядок так оценки может не перекрываются, поэтому нет неопределенного поведения. Это означает, что gcc
, clang
и Visual Studio
все в порядке. С другой стороны, необнуримые оценки допускают перекрывающиеся оценки, которые могут привести к неопределенному поведению, как указано ниже.
Из draft C++11 standard секции 1.9
[intro.execution]:
[...] Каждая оценка в вызывающей функции (в том числе других вызовов функций), не иначе конкретно секвенировал до или после того, как выполнение тела вызываемой функции неопределенно секвенировало относительно исполнения вызываемого function.9 [...]
и неопределенно секвенировали покрыта немного перед этим и говорит:
[...] Оценки А и В, когда последовательность неопределенно либо А секвенировали перед В или В секвенировали до того, как, но это не определено который. [Примечание. Неопределенно оценки секвенирования не могут перекрываться, но либо могут быть выполнены в первую очередь. -end примечание]
, который отличается от unsequenced оценок:
[...] Если A не секвенирован до B и B не секвенированы до A, то A и B не подвержены влиянию. [Примечание. Выполнение необоснованных оценок может перекрываться. -end примечание] [...]
, который может привести к непредсказуемому поведению (курсив мой ):
За исключением особо оговоренных случаев, оценки операндами отдельных операторов и подвыражениям индивидуального выражения не подвержены изменениям. [Примечание. В выражении, которое оценивается более одного раза во время выполнения программы, необнаружированные и неопределенно упорядоченные оценки его подвыражений не обязательно должны быть , выполняемые последовательно в разных оценках. -end note] Вычисления значений операндов оператора секвенированы перед вычислением значения результата оператора. Если побочный эффект от скалярного объекта unsequenced по отношению к любому другому побочному эффекту на тот же скалярном объект или вычисления значения с использованием значения одного и тем же скалярного объектом, поведение не определен [...]
Pre C++ 11
Pre C++11 порядок оценки подвыражения также не определено, но он использует sequence points в отличие от заказа. В этом случае есть точка последовательности при входе функции и выходе функции, что гарантирует отсутствие неопределенного поведения. Из секции 1.9
:
[...] Точки последовательности в функции-входа и выхода функции- (как описано выше), особенности вызовов функций, как оценивается, независимо от синтаксиса выражения, что вызывает функция бывает.
Прибивание вниз порядок оценки
Различного выбора, сделанный каждый компилятор может показаться неинтуитивным в зависимости от вашей точки зрения и ожиданий. Предметом приведения порядка оценки является предмет EWG issue 158: N4228 Refining Expression Evaluation Order for Idiomatic C++, который рассматривается для C++ 17, но кажется спорным based on the reactions to a poll on the subject. В документе содержится гораздо больше complicated case от «Язык программирования C++» 4-е издание. Который показывает, что даже те, у кого большой опыт работы на C++, могут сработать.
Если кто-то сделал «буфер (len + 1) [len_ = len] = '\ 0';" Я бы сказал им изменить его :) – paulm