(原創)後置 在不同編譯器中的行為

2021-04-14 07:38:40 字數 2588 閱讀 6430

intx = 0;

x = x++;

請問上述兩行**執行之後,

x的值是什麼?

有的同事說

1,有的同事說

0,究竟是什麼呢,試試就知道。

試了三個編輯器,

inter

,gcc和vc

自帶的cl

。inter

和gcc

得出的結果都是0,

vc得出的結果是1。

究竟哪個對呢?

讓我們再看看那兩行**,第一行不用多說,把乙個變數賦值為

0,第二行是由兩部分組成的,一部分是乙個賦值語句,也就是

operator =()

,一部分是後置

++操作符,也就是

operator ++()。後置

++的行為在

c++中的標準中有明確的定義:首先,取出當前運算元(本例為

x,下面均已

x代替)的值,放到乙個臨時變數中,例如

y,然後再把當前

x的值加上

1,然後返回那個臨時變數的值,也就是

y的值,這三個操作是乙個原子操作,中間不能插入其他**。所以,

operator ++

返回的是

x未加上

1之前的值。

這樣答案就很明顯了,按照

c++標準,先取出

x的值(例子中

x的初值為

0)放入y,

x加上1,這時

x的值是1,把

operator++

返回的y

的值(也就是

0)賦值給

x,這時,

x的值就從1變成

0了,由此可見,

inter

和gcc

在這個操作符的實現比

vc更符合

c++的標準。

operator- -()

也是得到相似的結果。

下面列出vc和

gcc所編譯出來的這兩行**的彙編**,可以更清楚的看出這兩個編譯器對後置操作符的實現。

先列出vc

的,我試了

vc.net 2003

和最新的

vc.net 2008

,得到的結果是一樣的。

int x = 0;

0041138emovdword ptr [x],0 ;

給x賦初值為0

x = x++;

00411395moveax,dword ptr [x] ;

取出x的值,放入eax中

00411398movdword ptr [x],eax ;

取出eax的值,放入x中,這兩句對應的c**是x = x,可以看出,先執行了賦值操作。

0041139bmovecx,dword ptr [x] ;

取出x的值,放入ecx中

0041139eaddecx,1 ;

把ecx中的值加1

004113a1movdword 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的值放入臨時變數,對x加

1,返回臨時變數的值,三步操作一口氣完成,中間不夾其他操作。

總結:在

operator ++

和operator =

一起出現的時候,

vc的實現先執行

operator =

,再執行

operator ++

,不符合

c++標準。而

gcc的實現就是符合

c++標準的。當然,在實際開發時不應寫這種晦澀難懂的**,一是你不能保證這種**在各種平台上的實現是一致的,二是維護起來也麻煩。

最後摘抄一段

c++ iso

文件的後置

++的描述。

++ 1

to it, unless the object is of type

bool

, in which case it is set to

true

.

4 複製建構函式在不同編譯器中的表現

classaa const a a a a f int main dev c 輸出結果 1 constructor called 10 constructor called 10 destructor called 10 destructor called visual studio輸出 結果 1 ...

在VDSP中編譯uclinux(3) 編譯器的差異

雖然vdsp和gcc3.2有很好的相容性,但是還是有一些差異的,以下列出已經碰到的一些差異及處理辦法 1 builtin expect exp,val 這是gcc的乙個內建函式,而vdsp無此函式,它用於為編譯器提供分支 資訊,其返回值是整數表示式exp的值,val的值必須是編譯時常數。這個內建函式...

三目運算子在C和C 編譯器中的不同

include using namespace std 在c語言中 表示式的結果 放在什麼地方 暫存器 1 在c語言中,表示式的返回值 是變數的值 在c 中,表示式返回的是變數的本身 2 如何做到的 讓表示式返回乙個記憶體空間 記憶體首位址 指標 在c語言中 如何 實現 c 的效果 3 本質 c 編...