關於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理論上也是
可以展開的。
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理論上也是
可以展開的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.