混淆内联函数的问题

时间:2009-10-21 15:23:46

标签: c++ optimization function inline

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

它说:“#语言规范可能允许程序对程序的参数做出额外的假设,而这些程序在内联程序后就无法再进行。”

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

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

3 个答案:

答案 0 :(得分:5)

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

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

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

最重要的是,可移植代码无法确保代码是否内联生成。但是,如果您不介意使代码不可移植,则可以使用__attribute__(noinline)

但是,我不会根据维基百科引用的引用来做这件事。维基百科几乎不是一个权威来源,即使它是,你所引用的只是一个模糊的陈述,关于某些假设条件下某些假设编译器的假设语言会发生什么。你通常最好编写代码以使其清晰可读,并让编译器担心从中产生好的结果。

答案 1 :(得分:1)

inline关键字是对编译器的建议或刺激。维基百科的定义似乎意味着通过使用这种关键字,您可以限制您可以使用该功能执行的操作。例如,您可能希望无法获取内联函数的地址。相反,C ++编译器采用相反的方法,即使函数被标记为内联,如果代码中的某个地方采用了所述函数的地址,那么该函数不会内联生成。

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

也许我在这里写的内容可以帮助您深入了解Coffin雄辩地表达的内联关键字需要编译器的内容。

答案 2 :(得分:-2)

当涉及到如何内联函数时,C / C ++已被明确规定。因此维基百科的特定评论不适用于这些语言。

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

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

如果foo内联在j上方的堆栈上发生的整数可能不是i。

相关问题