坚持到底就是胜利

用心去做好这件事情

统计

留言簿(1)

阅读排行榜

评论排行榜

inline

转载水木
误解:inline函数没有单独的函数体,也不能取地址。

inline修饰并不会改变函数的通常语义,仍可通过函数指针调用:

inline void f() {}

void g() {
  void (*p)() = f;
  p();
}


------------------------------------------------------------------------


误解:inline一定导致代码膨胀

class Foo {
public:
        int Bar() { return foo; }
private:
        int foo;
};

这样的Foo::Bar inline会让binary变小


------------------------------------------------------------------------


误解: inline函数一定是internal linkage/no linkage的。

inline与函数的linkage无关。inline函数同样可以用static和extern修饰,并具
备同一般函数相同的linkage。标准要求external linkage的inline函数在所有编
译单元中具有相同的地址。external linkage的inline函数内定义的静态变量同
样应在所有编译单元中表现为单一对象,具有相同的地址。


------------------------------------------------------------------------


误解: 如果inline函数包含循环/调用了其他函数/递归调用自己,编译器就无法
      将其展开。

某些早期的编译器有这类限制,但对现代编译器来说它们不再是inline展开的障
碍了。

[insert RoachCock's example here]


------------------------------------------------------------------------


误解:inline和virtual不能同时修饰一个函数。

inline和virtual并不冲突。以下程序编译通过。

#include <iostream>

struct A
{
  inline virtual void f()
  {
    std::cout << "inline virtual" << std::endl;
  }
};


------------------------------------------------------------------------


误解:virtual函数即使声明为inline,由于是late binding,无法判断实际
      调用的版本,编译器也无法展开。

虚函数调用并不总是late binding。

示例:

struct Base
{
  virtual void foo(){cout << "Base::foo" << endl;}
};

struct Derived : Base
{
  void foo(){cout << "Derived::foo" << endl;}
};

void bar(Base& b)
{
  b.foo();  // late binding. if b is a Derived, call Derived::foo
  b.Base::foo();  // early binding. inline
  Derived d;
  d.foo();  // early binding. inline
}

另外,尽管在您的编译器中很可能还没有实现,但即使late binding理论上也是
可以展开的。

posted on 2006-07-05 20:10 ailab 阅读(397) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理