有什么有趣的这个问题是,它只是使编译器相关的。使用锵/ LLVM:
#include <iostream>
using namespace std;
inline int foo(int a) { return a << 1; }
struct Bar
{
int a;
Bar(int x) : a(x) {}
Bar baz() { return a << 1; }
};
void out(int x) __attribute__ ((noinline));
void out(int x) { cout << x; }
void out(Bar x) __attribute__ ((noinline));
void out(Bar x) { cout << x.a; }
void f1(int x) __attribute ((noinline));
void f1(int x) { out(foo(x)); }
void f2(Bar b) __attribute ((noinline));
void f2(Bar b) { out(b.baz()); }
int main(int argc, char** argv)
{
f1(argc);
f2(argc);
}
给出the following IR:
define void @_Z3outi(i32 %x) uwtable noinline {
%1 = tail call %"class.std::basic_ostream"*
@_ZNSolsEi(%"class.std::basic_ostream"* @_ZSt4cout, i32 %x)
ret void
}
define void @_Z3out3Bar(i32 %x.coerce) uwtable noinline {
%1 = tail call %"class.std::basic_ostream"*
@_ZNSolsEi(%"class.std::basic_ostream"* @_ZSt4cout, i32 %x.coerce)
ret void
}
define void @_Z2f1i(i32 %x) uwtable noinline {
%1 = shl i32 %x, 1
tail call void @_Z3outi(i32 %1)
ret void
}
define void @_Z2f23Bar(i32 %b.coerce) uwtable noinline {
%1 = shl i32 %b.coerce, 1
tail call void @_Z3out3Bar(i32 %1)
ret void
}
而且不出所料,所产生的组件仅仅是相同的:
.globl _Z2f1i
.align 16, 0x90
.type _Z2f1i,@function
_Z2f1i: # @_Z2f1i
.Ltmp6:
.cfi_startproc
# BB#0:
addl %edi, %edi
jmp _Z3outi # TAILCALL
.Ltmp7:
.size _Z2f1i, .Ltmp7-_Z2f1i
.Ltmp8:
.cfi_endproc
.Leh_func_end2:
.globl _Z2f23Bar
.align 16, 0x90
.type _Z2f23Bar,@function
_Z2f23Bar: # @_Z2f23Bar
.Ltmp9:
.cfi_startproc
# BB#0:
addl %edi, %edi
jmp _Z3out3Bar # TAILCALL
.Ltmp10:
.size _Z2f23Bar, .Ltmp10-_Z2f23Bar
.Ltmp11:
.cfi_endproc
.Leh_func_end3:
通常,只要在类的方法是内联,this
参数和参考可以轻松省略。我不太清楚海湾合作委员会如何搞砸这件事。
'constexpr'会很有用,我怀疑你会对右值引用有任何用处,因为你的课程首先会很便宜。使用大量的内联,保持你的构造函数和析构函数不重要,你应该看到很好的性能。 – 2012-03-12 05:01:50