GCC会内联一个带指针的函数吗?

Joe*_*Joe 14 c optimization gcc pointers inline

我有一个函数,它对一段数据进行操作(比方说,一个int),我想通过传递对valule的引用来改变它.因此,我有这个功能:void myFunction(int *thing) { ... }.当我使用它时,我称之为:myFunction(&anInt).

由于我的功能经常被调用(但是来自许多不同的地方),我担心它的性能.我将其重构为函数的原因是可测试性和代码重用.

编译器是否能够优化函数,将其内联直接操作我的anInt变量?

我希望你能在这个问题的精神中接受这个问题(即我不会过早地担心优化,我对答案感到好奇).同样,我不想把它变成一个宏.

Nik*_*sov 18

找出函数是否内联的一种方法是使用-Winlinegcc选项:

-Winline
  Warn if a function can not be inlined and it was declared as inline.
  Even with this option, the compiler will not warn about failures to inline
  functions declared in system headers.

  The compiler uses a variety of heuristics to determine whether or not to
  inline a function. For example, the compiler takes into account the size
  of the function being inlined and the amount of inlining that has already
  been done in the current function.  Therefore, seemingly insignificant
  changes in the source program can cause the warnings produced by -Winline
  to appear or disappear.


ntd*_*ntd 9

海湾合作委员会非常聪明.考虑以下代码片段:

#include <stdio.h>

void __inline__ inc(int *val)
{
    ++ *val;
}

int main()
{
    int val;

    scanf("%d", &val);

    inc(&val);

    printf("%d\n", val);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

之后 gcc -S -O3 test.c你获得以下相关的asm之后:

...
call    __isoc99_scanf
movl    12(%rsp), %esi
movl    $.LC1, %edi
xorl    %eax, %eax
addl    $1, %esi
movl    %esi, 12(%rsp)
call    printf
...
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,没有必要成为asm专家才能看到inc()调用已转换为增量指令.


小智 7

这里有两个问题 - 代码可以优化,并且可以.它当然可以,但"意志"取决于优化器所处的情绪.如果这对您来说非常重要,请编译代码并查看汇编语言输出.

此外,您似乎在混淆两个问题.内联函数有效地将其正文粘贴在呼叫站点上.你是否使用指针既不在这里,也不在那里.但你似乎在问编译器是否可以转换:

int x = 42;
int * p = & x;
* p = * p + 1;
Run Code Online (Sandbox Code Playgroud)

x = x + 1;
Run Code Online (Sandbox Code Playgroud)

这对于优化者来说要困难得多.

  • 不要介意它是否是指向结构的指针,在这种情况下,编译器必须应用指针算法.或者至少使用地址寄存器(包含结构的地址)和偏移来访问结构的字段.内联后这种情况可能没有区别. (2认同)