C++ 具有小型结构调用约定优化,其中编译器在函数参数中传递小型结构与传递原始类型(例如,通过寄存器)一样有效。例如:
class MyInt { int n; public: MyInt(int x) : n(x){} };
void foo(int);
void foo(MyInt);
void bar1() { foo(1); }
void bar2() { foo(MyInt(1)); }
Run Code Online (Sandbox Code Playgroud)
bar1()并bar2()生成几乎相同的汇编代码,除了分别调用foo(int)和foo(MyInt)。特别是在 x86_64 上,它看起来像:
mov edi, 1
jmp foo(MyInt) ;tail-call optimization jmp instead of call ret
Run Code Online (Sandbox Code Playgroud)
但是如果我们测试std::tuple<int>,它会有所不同:
void foo(std::tuple<int>);
void bar3() { foo(std::tuple<int>(1)); }
struct MyIntTuple : std::tuple<int> { using std::tuple<int>::tuple; };
void foo(MyIntTuple);
void bar4() { foo(MyIntTuple(1)); }
Run Code Online (Sandbox Code Playgroud)
生成的汇编代码看起来完全不同,小尺寸的struct( std::tuple<int>)是通过指针传递的:
sub rsp, 24 …Run Code Online (Sandbox Code Playgroud)