2012-02-03 38 views
1

當我用ARMCC編譯我的代碼時,有一個問題。以下是我的代碼(代碼僅用於測試)。ARMCC如何優化C++代碼

void COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi& aObject) 
{ 
if(NULL == &aObject) 
    { 
    RDebug::Printf("This is for testing reference,add:%P", &aObject); 
    aObject.HandleStatusPaneSizeChange(); 
    } 
} 

使用-asm -interleave編譯我的發行版本,我有以下輸出。只有一個ASM聲明產生。函數主體中的所有代碼均已丟失。

COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi&) 
;;;216  
;;;217 void COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi& aObject) 
000254 4770    BX  lr 
;;;218  { 
;;;219  if(NULL == &aObject) 
;;;220   { 
;;;221   RDebug::Printf("This is for testing reference,add:%P", &aObject); 
;;;222   aObject.HandleStatusPaneSizeChange(); 
;;;223   } 
;;;224  } 
;;;225 

然後,我編譯它加入-O0,然後我得到以下輸出。這裏所有的代碼都有自己的ASM指令。

    _ZN15COptimizerAppUi16DoRealWorksByRefERS_ PROC ; 
COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi&) 
;;;216  
;;;217 void COptimizerAppUi::DoRealWorksByRef(COptimizerAppUi& aObject) 
000328 b570    PUSH  {r4-r6,lr} 
;;;218  { 
00032a 0005    MOVS  r5,r0 
00032c 000c    MOVS  r4,r1 
;;;219  if(NULL == &aObject) 
00032e 2c00    CMP  r4,#0 
000330 d108    BNE  |L1.836| 
;;;220   { 
;;;221   RDebug::Printf("This is for testing reference,add:%P", &aObject); 
000332 0021    MOVS  r1,r4 
000334 a01a    ADR  r0,|L1.928| 
000336 f7fffffe   BL  _ZN6RDebug6PrintfEPKcz ; RDebug::Printf(const char*, ...) 
;;;222   aObject.HandleStatusPaneSizeChange(); 
00033a 6820    LDR  r0,[r4,#0] 
00033c 3080    ADDS  r0,r0,#0x80 
00033e 6a81    LDR  r1,[r0,#0x28] 
000340 0020    MOVS  r0,r4 
000342 4788    BLX  r1 
        |L1.836| 
;;;223   } 
;;;224  } 
000344 bd70    POP  {r4-r6,pc} 
;;;225  
          ENDP 

那麼根據比較兩個輸出,我知道COptimizerAppUi的身體::是由編譯器去除DoRealWorksByRef。是的,我知道有-O0,-O1,-O2,-O3來控制優化的行爲。但是我搜索了很多資料,並沒有得到編譯器如何優化代碼。那麼你有沒有關於編譯優化的規則?任何意見/詳細信息,歡迎。

在此先感謝。

順便說一句,在我的環境: C:\

器armcc

ARM C/C++編譯器,RVCT4.0 [構建902]

回答

3

請閱讀這個問題的答案:

Is null reference possible?

引用不是指針。引用不允許爲NULL。您的條件NULL == &aObject將始終評估爲false。編譯器知道這一點,所以它知道你的函數永遠不會做任何事情。當您開啓優化時,它會使用這些知識縮短您的功能。

5

C++標準規定,獲取對NULL的引用將調用未定義的行爲。因此,編譯器正在利用這些知識來完全優化您的if檢查 - 也就是說,參照NULL是非法的,因此您的if語句在格式良好的程序中永遠不會成立。或者換句話說,如果你有一個對NULL的引用,你的代碼是無效的,所以程序可以免費使用。

0

首先感謝您的回答。我做了另一個測試,代碼如下所示。 ShowLength函數可以真正輸出一些具有優化功能的東西。 G ++和CL輸出。

#include <iostream> 
#include <vector> 

using namespace std; 

void ShowLength(vector<int>& vec) 
{ 
    if(0 == &vec) 
    { 
     cout << "vec::lenght = 0" << endl; 
    } 
} 

int main(int argc, char* arv[]) 
{ 
    vector<int> *p = 0; 
    vector<int> &ref = *p; 
    ShowLength(ref); 

    return 0; 
}