2017-03-02 60 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; 
} 

内联的过程不仅仅是“复制和粘贴”,所产生的代码有在它被注入的代码中有意义。编译器可以根据需要自由地修改和优化内联代码,同时保持原代码的语义