2016-05-10 28 views
3

一位朋友写了一个函数,大约有300行代码,并问我如何将它变成内联。只能调用一次的大函数是内联的吗?

我告诉他这太大了,会导致指导性通货膨胀。然后我想,但他只调用一次这个函数。所以,没有缺点。

感觉不对。这是错的吗?

+3

为什么不看产生的装配而不是猜测? – StoryTeller

+0

标准中没有什么可以说它不能。这一切都归结于你正在使用的编译器以及它在优化时的激进程度。 – Sean

+1

请详细说明您正在使用的编译器和编译器设置。这非常适合编译器,如果您期待的答案涵盖所有过于宽泛的情况。 – NathanOliver

回答

9

Gcc做了这个优化。当静态函数一旦被内联就被调用。它不会对外部函数执行此操作,因为它无法确定谁调用该函数。

您可以通过这里检查汇编:

https://gcc.godbolt.org/

首先与EXTERN功能:

#include <stdio.h> 

extern int test(int x); 

int main() { 
    int x = test(10); 

    printf("%d\n", x); 
} 

int test(int x) 
{ 
    volatile int y = x; 
    for (int i = 0; i < 10; i++) 
    y++; 
    for (int i = 0; i < 10; i++) 
    y++; 

    return y; 
} 

的主要()与-O优化,编译器,汇编程序输出标记:

main: 
     subq $8, %rsp 
     movl $10, %edi 
     call test(int) 
     movl %eax, %esi 
     movl $.LC0, %edi 
     movl $0, %eax 
     call printf 
     movl $0, %eax 
     addq $8, %rsp 
     ret 

您可以看到测试被调用并且EAX中的返回值存储在$ 0中。

现在让测试静态并观察测试调用消失并且代码被内联。

+0

不完全正确的时代,我们有链接时间优化。根本没有必要考虑内联或不内联!也许该函数被内联多次,但与来自调用者的其他常量。许多其他场景可能... – Klaus

0

如果您要使用此功能两次,请不要内联,但如果您只使用一次,则可以内联。

+1

内联由编译器/优化器完成。如果统计数据表明内联更好,他会内联。不要考虑优化器。编译器的这一部分比你认为的更好! – Klaus

+3

Downvoters是惊人的。只赞扬新的答案,说完全一样的东西。大声笑 –

4

一个大功能可以内联。 如果它只被调用一次,那么没有缺点(除了您将来可能开始调用它的可能性之外)。

编译器是否实际优化了调用(扩展了呼叫站点的功能)是另一回事。如果函数具有内部链接,则很容易证明该函数只被调用一次。如果它具有外部连接,那么只有在整个程序优化时才有可能。