1

在维基百科中的内联函数问题中: http ://en.wikipedia.org/wiki/Inline_expansion#Problems

它说:“# 语言规范可能允许程序对过程的参数做出额外的假设,这些假设在过程被内联后它不能再做出。”

有人可以详细说明这一点吗?

如何防止 GCC 内联 C++ 函数?

4

3 回答 3

5

在 C++ 中,inline关键字实际上只有一个必需的含义:单一定义规则为该函数暂停(例如,该函数可以在多个翻译单元中定义,并且代码仍然符合)。

具体来说,使用inline关键字并不能确保该函数的代码将内联生成。在类定义中定义一个函数也使它成为一个内联函数——但同样,这并不能确保它的代码也将内联生成。

相反,在类定义之外定义的没有inline关键字的函数可以并且可能仍然内联生成其代码。唯一的区别是,在这种情况下,函数的多个定义会导致代码不一致。

底线是可移植代码不能保证代码是内联生成还是非内联生成。但是,如果您不介意使代码不可移植,则可以使用__attribute__(noinline).

但是,我不会根据 Wikipedia 引用的引文来做这件事。Wikipedia 几乎不是权威来源,即使是,您所引用的只是关于在某些假设条件下在某些假设编译器上使用某些假设语言可能会发生什么的模糊陈述。通常,您最好编写清晰易读的代码,并让编译器担心由此产生良好的结果。

于 2009-10-21T16:09:53.773 回答
1

inline 关键字是对编译器的建议或刺激。维基百科的定义似乎暗示通过使用这种关键字,您可以限制您可以使用该函数执行的操作。例如,您可能认为不可能获取内联函数的地址。相反,C++ 编译器采取相反的策略,即使函数被标记为内联,如果在代码中的某处采用了所述函数的地址,则不会内联生成该函数。

类似地,如果一个函数是虚拟的,则(显然)不能内联生成,但这仍然不会使多态函数的内联定义非法。

也许我在这里写的内容会让您深入了解编译器需要对 Coffin 雄辩地表达的 inline 关键字做什么。

于 2009-10-21T16:34:34.903 回答
-2

当谈到如何内联函数时,C/C++ 得到了很好的说明。因此,来自维基百科的特定评论不适用于这些语言。

假设 C 语言规范要求函数调用参数以相反的顺序在堆栈上传递(编辑:并且堆栈总是向下增长,并且参数之间没有填充)。实际上,它们通常是,但您不能假设这总是正确的。下面的代码在这个陌生的世界中是有效的。

void foo( int i, int j )
{
  int myi = &j[1];
  return myi + j;
}

如果 foo where inlined 出现在 j 之上的堆栈上的整数可能不是 i。

于 2009-10-21T15:36:56.273 回答