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. Весь код в теле функции отсутствует.

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++ Compiler, RVCT4.0 [Построить 902]

ответ

3

Пожалуйста, прочитайте ответ на этот вопрос:

Is null reference possible?

Ссылки не указатели. Ссылки не могут быть NULL. Ваше состояние NULL == &aObject всегда будет оцениваться как ложное. Компилятор знает это, поэтому он знает, что ваша функция никогда ничего не сделает. Когда вы включаете оптимизацию, он использует эти знания для сокращения вашей функции.

5

Стандарт C++ диктует, что получение ссылки на NULL вызывает неопределенное поведение. Таким образом, компилятор использует эти знания, чтобы полностью исключить ваш if, то есть незаконно иметь ссылку на NULL, поэтому ваш оператор if никогда не должен быть правдой в хорошо сформированной программе. Или, другими словами, если у вас есть ссылка на NULL, ваш код недействителен, поэтому программа может свободно работать с haywire.

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; 
} 
Смежные вопросы