2017-03-02 36 views
2

讓說,我有一個內聯函數像this編譯器如何管理返回內聯函數?

inline double CalculateValue() { 
    // some condition 
    if (true) { 
     // some other condition 
     if (true) { 
      // another condition 
      if (true) { 
       return 1.0; 
      } 

      // somethings 
      std::cout << "inside1" << std::endl; 
     } 

     // somethings 
     std::cout << "inside2" << std::endl; 
    } 

    return 2.0; 
} 

void Process() { 
    double value = CalculateValue(); 

    value *= 100.0; 

    std::cout << value << std::endl; 
} 

int main() 
{ 
    Process(); 
} 

,將「複製和粘貼」的CalculateValue()函數內的Process()之一。正如預期的那樣,結果是100

但是,如果我嘗試emulate如何「複製和粘貼」將執行,有件事情我不明白:

void Process() { 
    double value; 

    // some condition 
    if (true) { 
     // some other condition 
     if (true) { 
      // another condition 
      if (true) { 
       value = 1.0; 
       return; 
      } 

      // somethings 
      std::cout << "inside1" << std::endl; 
     } 

     // somethings 
     std::cout << "inside2" << std::endl; 
    } 

    value = 2.0; 

    value *= 100.0; 

    std::cout << value << std::endl; 
} 

int main() 
{ 
    Process(); 
} 

當然,當它到達return聲明,該函數的其餘部分必須被忽略(即inside1inside2絕不能被打印),因爲return。但是,如果我從0123.父功能(Process()),它立即返回,所以我永遠不會看到100

這意味着它以另一種方式。

編譯器如何管理這種情況?我試圖創建一個代碼塊,但仍然return返回到主函數...

+1

編譯器顯然不使用return,我不知道確切使用了哪一個,但有很多其他選項,例如' while(1){... break; }'甚至'goto'或者一些比較模糊的步驟會導致asm – slawekwin

+0

'inline'不會改變函數調用的語義,只會導致鏈接。 – sp2danny

回答

2

在寫您的「模擬」時,您忘記處理return之一。在內聯函數中,編譯器會用goto語句替換它。

void Process() { 
    double value; 

    // begin of inlined function 

    // some condition 
    if (true) { 
     // some other condition 
     if (true) { 
      // another condition 
      if (true) { 
       value = 1.0; 
       goto next;  // <<<<<<<<<<<<<<<<<<< return replaced by goto 
      } 

      // somethings 
      std::cout << "inside1" << std::endl; 
     } 

     // somethings 
     std::cout << "inside2" << std::endl; 
    } 

    value = 2.0; 
next: 
    //end of inlined function 

    value *= 100.0; 

    std::cout << value << std::endl; 
} 
+1

編程不是'goto'邪惡嗎? :) – markzzz

+0

你認爲「if-then-else」的背景是什麼? 'goto'本身不壞*(作爲一把刀),只有它的用法可以是好的或壞的。 –

+0

@ Jean-BaptisteYunèspaizza的評論可能意味着諷刺。 –

0

在這種情況下,內聯代碼會認爲return更像是一個goto,如:

void Process() { 
    double value; 

    // some condition 
    if (true) { 
     // some other condition 
     if (true) { 
      // another condition 
      if (true) { 
       value = 1.0; 
       goto nextStep; 
      } 

      // somethings 
      std::cout << "inside1" << std::endl; 
     } 

     // somethings 
     std::cout << "inside2" << std::endl; 
    } 

    value = 2.0; 

nextStep: 

    value *= 100.0; 

    std::cout << value << std::endl; 
} 

內聯的過程不僅僅是「複製和粘貼」,所產生的代碼有在它被注入的代碼中有意義。編譯器可以根據需要自由地修改和優化內聯代碼,同時保持原代碼的語義

相關問題