2009-10-21 78 views
1

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

它说:“#语言规范可以让一个程序来做出有关参数的附加假设,程序,它可以不再在程序内联后制作。“

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

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

+1

“你如何防止GCC内联C++函数?”通常情况下,这是一个错误的问题。正确的问题经常是“为什么要阻止GCC内嵌C++函数?” – sbi 2009-10-21 15:29:42

+0

我相信原因与别名有关。当只调用一个函数时,编译器可以忽略调用函数中的指针,该指针可能会替代被调用函数中指向的对象。内联时,被调用函数的代码与调用函数中的代码在同一个块中执行,并且别名成为问题。 – 2009-10-21 15:36:06

+0

@litb,我还没有看到它。我们能看到一个具体的例子吗? – 2009-10-21 16:39:07

回答

5

在C++中,inline关键字实际上只具有一个需要含义:表示一定义规则被暂停该功能(例如,功能可以以若干翻译单元所定义,和码仍符合)。

具体而言,使用inline关键字不能确保该函数的代码将以内联方式生成。在类定义中定义一个函数也会使它成为一个内联函数 - 但是,这又不能确保它的代码会以内联的方式生成。

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

底线是便携式代码不能保证代码是或不是内嵌生成的。但是,如果您不介意让代码不可移植,则可以使用__attribute__(noinline)

但是,我不会在维基百科引用的引用的基础上做到这一点。维基百科几乎不是一个权威的来源,即使是这样,即使是这样,你所引用的只是对某些假设条件下某些假设编译器的假设语言会发生什么的模糊声明。编写代码清晰易读并且让编译器担心从中产生好的结果会更好。

-2

关于如何内联函数,C/C++是非常明确的。所以维基百科的特别评论不适用于这些语言。假设C语言规范要求函数调用参数以相反的顺序在堆栈上传递(编辑:并且堆栈总是向下生长,并且在参数之间没有填充)。实际上他们通常都是,但是你不能认为这是真的。下面的代码在这个奇怪的世界中是有效的。

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

如果foo里面出现的整数发生在栈上面,j可能不是i。

+2

-1在任何现实中,此代码的结果未在C++规范中定义。很难看出你的回答将如何帮助提问者获得内联关键字的使用/误用清晰度。 – Elemental 2009-10-21 16:23:36

+0

问题是两个部分。澄清“语言规范”评论以及如何在C++中禁用内联。维基百科的“language specificaiton”评论不适用于c/C++,所以我发明了一个类似于C的语言。我绝不会声称我写的是有效的C++甚至c。我试图用“假设”和“在这个陌生的世界” – 2009-10-21 16:30:57

1

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

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

也许我在这里写的内容将让您深入了解编译器需要如何用Coffin雄辩地表达的内联关键字。