2012-02-03 3 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文は1つだけです。関数の本体にあるすべてのコードがありません。

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 

だから2つの出力の比較によると、私はCOptimizerAppUiの体を知っている:: DoRealWorksByRefは、コンパイラによって除去しました。はい、私は最適化の動作を制御する-O0、-O1、-O2、-O3があることを知っています。しかし、私は非常に多くの資料を検索し、どのようにコンパイラがコードを最適化するのか分からなかった。コンパイラの最適化に関する規則はありますか?コメント/詳細情報は大歓迎です。

ありがとうございます。私の環境ではところで

、: C:

のARM C/C++コンパイラ、RVCT4.0のarmcc \ [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; 
} 
関連する問題