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

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

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

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

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

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

 #include  void __inline__ inc(int *val) { ++ *val; } int main() { int val; scanf("%d", &val); inc(&val); printf("%d\n", val); return 0; } 

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 ... 

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

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

 -Winline
  如果函数无法内联并且声明为内联,则发出警告。
  即使使用此选项,编译器也不会警告内联失败
  系统头中声明的函数。

  编译器使用各种启发式方法来确定是否
  内联函数。 例如,编译器会考虑大小
  内联函数和已经内联的数量
  已在当前function中完成。 因此,看似微不足道
  源程序中的更改可能会导致-Winline生成警告
  出现或消失

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

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

 int x = 42; int * p = & x; * p = * p + 1; 

 x = x + 1; 

优化者看到这一点要困难得多。

参数是否是指针无关紧要。

但首先,如果编译器应该自动内联函数,它必须是静态的。 它必须包含在同一个编译单元中。 注意:我们谈论的是C,而不是C ++。 C ++内联规则有所不同。

如果无法在同一编译单元中使用该函数,请尝试全局优化(有关详细信息,请查看编译器的文档)。

C99为您提供“内联”关键字,就像在C ++中一样。 这将限制提升到编译单元。

这是一些进一步的信息 。

它会(或至少可以)。 有一些原因导致函数无法内联 – 例如,当您尝试访问函数的指针(通过引用调用函数)时,您通过引用访问参数,这是正常的。 可能还有其他情况(静态变量?不确定)

尝试使用“extern inline”声明该函数 – 这可以防止编译器发出独立的主体。 如果它无法内联函数,则会发出错误。

如果您担心编译器生成次优代码并想要更改简单的值类型,请将函数声明为int myFunction(int)并返回新值。

您使用的是什么编译器版本? 有什么选择? 在什么平台上?

所有这些问题都会影响答案。 您确实需要编译代码并查看程序集。

这看起来像是一个过早优化的经典案例。 你真的知道这里有性能问题吗? 一个值得浪费你宝贵时间的人担心。 我的意思是, 真的知道吗? 比如,你测量过吗?

这本身并不算太糟糕,但如果你对大量的代码采取这种态度,你可以做一些严重的破坏,浪费大量的开发和维护时间,没有充分的理由。