zoukankan      html  css  js  c++  java
  • 后置++在不同编译器中的行为

     int  x = 0;

    x = x++;

     

    请问上述两行代码执行之后,x的值是什么?

    有的同事说1,有的同事说0,究竟是什么呢,试试就知道。

    试了三个编辑器,Intergccvc自带的cl

    Intergcc得出的结果都是0vc得出的结果是1

    究竟哪个对呢?

    让我们再看看那两行代码,第一行不用多说,把一个变量赋值为0,第二行是由两部分组成的,一部分是一个赋值语句,也就是 operator =(),一部分是后置++操作符,也就是operator ++()

    后置++的行为在c++中的标准中有明确的定义:首先,取出当前操作数(本例为x,下面均已x代替)的值,放到一个临时变量中,例如y,然后再把当前x的值加上1,然后返回那个临时变量的值,也就是y的值,这三个操作是一个原子操作,中间不能插入其他代码。所以,operator ++返回的是x未加上1之前的值。

    这样答案就很明显了,按照c++标准,先取出x的值(例子中x的初值为0)放入yx加上1,这时x的值是1,把operator++返回的y的值(也就是0)赋值给x,这时,x的值就从1变成0了,由此可见,Intergcc在这个操作符的实现比VC更符合c++的标准。

    operator- -() 也是得到相似的结果。

    下面列出VCgcc所编译出来的这两行代码的汇编代码,可以更清楚的看出这两个编译器对后置操作符的实现。

    先列出VC的,我试了vc.net 2003和最新的vc.net 2008,得到的结果是一样的。

         int x = 0;

    0041138E  mov         dword ptr [x],0 ; 给x赋初值为0

         x = x++;

    00411395  mov         eax,dword ptr [x]  ; 取出x的值,放入eax中

    00411398  mov         dword ptr [x],eax  ; 取出eax的值,放入x中,这两句对应的c代码是x = x,可以看出,先执行了赋值操作。

    0041139B  mov         ecx,dword ptr [x] ; 取出x的值,放入ecx中

    0041139E  add         ecx,1 ; 把ecx中的值加1

    004113A1  mov         dword ptr [x],ecx ; 把ecx中的值赋值给x,以上三句执行的是c代码更像是++x。

    以上就是VC编译出来的代码,按这样的代码执行,得到的结果当然是1,从上面的汇编代码可以看出,在VC的实现中,如果operation ++ operator = 一起出现时,先执行的是operator =

    接下来,我们看看gcc编译出的汇编代码。

    movl $0, -4(%ebp) ; 把x初始化为0

    movl -4(%ebp), %edx ; 把x的值放入到edx中,edx的值就会作为opeator ++的返回值

    leal -4(%ebp), %eax ; 取出x的地址,放入eax中

    incl (%eax) ; 把eax中的值加1,实际上就是对x的值加1,执行之后,x=1

    movl %edx, -4(%ebp) ; 把edx的值赋值给x,执行之后,x=0

    由此可见,gcc的实现完全符合c++标准中的实现,把x的值放入临时变量,对x1,返回临时变量的值,三步操作一口气完成,中间不夹其他操作。

    总结:在operator ++ operator = 一起出现的时候,VC的实现先执行 operator =,再执行 operator ++,不符合c++标准。而gcc的实现就是符合c++标准的。当然,在实际开发时不应写这种晦涩难懂的代码,一是你不能保证这种代码在各种平台上的实现是一致的,二是维护起来也麻烦。

    最后摘抄一段c++ iso文档的后置++的描述。

    The value obtained by applying a postfix ++ is the value that the operand had before applying the operator.[Note:the value obtained is a copy of the original value ] The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a complete object type. After the result is noted, the value of the object is modified by adding 1 to it, unless the object is of type bool, in which case it is set to true.

     
    注:在最新的gcc编译器上,发现结果也是等于1;看汇编的结论是X=X++等同于X++;
  • 相关阅读:
    HDU 3547 DIY Cube
    POJ 2975 Nim
    POJ 1678 I Love this Game!
    POJ 2234 Matches Game
    POJ 3537 Crosses and Crosses
    POJ 3710 Christmas Game
    POJ 1704 Georgia and Bob
    HDU 3923 Invoker
    POJ 2154 Color
    PLM更新自定义CLASS
  • 原文地址:https://www.cnblogs.com/xiayong123/p/3717170.html
Copyright © 2011-2022 走看看