Я пытаюсь реализовать простой компилятор с помощью flex & бизон, и застрял в записи постфикса.
(Компилятор должен вести себя как компилятор C ++)
Вот проблема:
Учитывая следующий код:
int x = 0;
int y = x++ || x++ ; //y=1 , x = 2 this is understandable
int z = x++ + x++ ; // z = 0 , x=2
первая строка в порядке из-за следующей грамматики:
expression = expression || expression; // x=0
expression = 0 || expression // x= 1
expression = 0 || 1 //x=2
expression = 1 // x=2
y = 1
Однако я не понимаю, почему z = 0.
Когда моя грамматика бизонов видит «переменную» ++, она сначала возвращает значение переменных, и только затем увеличивает его на 1. Я привык думать, что так работает C ++, но он не будет работать для переменной «z».
Любой совет, как решить это дело?
int z = x++ + x++;
Хотя z может показаться равным 0, это не так, на самом деле это может быть любое значение, и оно будет полностью зависеть от используемого вами компилятора. Это потому, что присваивание z имеет неопределенное поведение.
Неопределенное поведение происходит из-за того, что значение x изменяется более одного раза между точками последовательности. В C ++ || Оператор — это точка последовательности, поэтому назначение y работает так, как ожидается, однако оператор + не является точкой последовательности.
Конечно, в C ++ есть и другие точки последовательности; быть более ярким примером.
Следует также отметить, что оператор ++ возвращает предыдущее значение переменной, то есть в этом примере
#include <iostream>
using namespace std;
int main() {
int x = 0;
int y = x++;
cout << y << endl;
return 0;
}
Значение, напечатанное для y, равно 0.
Сказать то же самое по-другому. Компилятор C свободен для реализации
int z = x++ + x++;
как либо
z = x + x
incr x
incr x
или как
int r1 = x;
incr x
z = r1 + x
incr x
Ваш компилятор, похоже, использует первый план.