Порядок вычисления выражения всегда был источником неопределенного поведения в C ++. Наконец, в стандарте C ++ 11 указано, каким должен быть порядок оценки?
Знаем ли мы теперь значения var1
а также var2
следующего выражения:
int var1 =10, var2=20;
var1 = var2 = 30;
Это случится var1=30 and var2=30
, или же var1=20 and var2=30
?
var1 = var2 = 30;
Оба должны быть 30
и это указано стандартом. Что не указано, так это то, что если присваивающие операнды являются сложным выражением, которое должно быть оценено перед присвоением, какова последовательность их оценки?
(expr1) = (expr2) = x;
1 2
or
(expr1) = (expr2) = x;
2 1
Нет, новый стандарт не определяет последовательность или же упорядочение вычислений всех подвыражений.
Выражение a + b + c
сгруппирован грамматически как (a + b) + c
, но три подвыражения a
, b
а также c
могут быть оценены в любом порядке, и оценки не упорядочены по отношению друг к другу.
Чтобы сделать это более конкретным, рассмотрим:
int main()
{
return printf("Hello") + printf("World") + printf("\n");
}
Что касается вашего кода: там нет никакой двусмысленности. Это одно выражение, выражение присваивания формы a = b
, где a
это значение var1
а также b
это подвыражение var2 = 30
, Тот факт, что вам интересно, var1
заканчивается как 20
или как 30
заставляет меня поверить, что вы не уверены в ассоциативности операторов (для =
). Это, однако, никогда не было двусмысленным и прекрасно определено во всех языковых вариантах, которые я могу придумать. Оператор присвоения ассоциируется справа, что приводит к подвыражениям a
а также b
что я описал. Этот (чрезвычайно фундаментальный) аспект языка не был изменен в C ++ 11.
Если вы действительно хотите объединить две проблемы, вы должны рассмотреть следующее выражение:
var1 = 10;
(var1 = 20) = (var2 = var1);
Теперь последнее выражение также a = b
, но оба a
а также b
являются нетривиальными подвыражениями, чья оценка не приказал.
Оператор присваивания (=) и составные операторы присваивания все группы справа налево.
Это ничего не говорит нам о порядке оценки. Это просто означает, что a = b = c
анализируется как a = (b = c)
и не (a = b) = c
,
1.9/15
все еще применяется:
За исключением отмеченных случаев, оценки операндов отдельных операторов и подвыражений отдельных выражений не являются последовательными.
Правила секвенирования вводят только частичное упорядочение. В выражении, подобном этому:
(x+42) = (y+42)
гарантируется, что оба подвыражения (x+42)
а также (y+42)
выполняются до того, как произойдет присваивание результата (x + 42), но сами два подвыражения не упорядочены. Любой из них может быть выполнен раньше другого, и они могут даже чередоваться, и порядок выполнения не должен быть последовательным во время выполнения программы.