如何在野牛中模拟C ++ postfix?

时间:2012-12-01 12:48:40

标签: c++ compiler-construction bison

我正在尝试使用flex& amp;来实现一个简单的编译器。野牛,并陷入后缀符号。 (编译器应该像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'变量。

有关如何解决此案的任何建议?

2 个答案:

答案 0 :(得分:2)

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。

答案 1 :(得分:0)

用另一种方式说同样的话。 C编译器可以自由实现

int z = x++ + x++;

作为

 z = x + x
 incr x
 incr x

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

您的编译器似乎正在使用第一个计划。