конструкция компилятора — Как мне эмулировать постфикс C ++ в бизоне?

Я пытаюсь реализовать простой компилятор с помощью 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».

Любой совет, как решить это дело?

3

Решение

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.

2

Другие решения

Сказать то же самое по-другому. Компилятор C свободен для реализации

int z = x++ + x++;

как либо

 z = x + x
incr x
incr x

или как

 int r1 = x;
incr x
z = r1 + x
incr x

Ваш компилятор, похоже, использует первый план.

0

По вопросам рекламы [email protected]