我是作者(yuanzhubi) 我来简单说几句开发时的一些体验。
0. call_in_stack就是让一个函数用任何一块内存作为栈来执行的库,纯头文件的。可以让协程创建的时候少分配些栈,执行函数的时候再按需使用。支持C++03(使用右值需要配置头文件里或者编译的时候定义一个红。)。
1. 我工作的开发场景是C++ 03。所以右值的支持放到最近才支持,也没有使用变长模版参数这样的特性。
2. call_in_stack最早的名字是call_with_stack, 结果发现arm linux内核中有一个类似的同名函数(功能也类似,但是只固定支持一个void*参数,用起来颇似线程创建。。),所以把with换成了in。
3. X64和x86 gcc不支持naked属性,我却需要写很多内嵌汇编,那么编译器进入一个函数到底会不会默认push ebp呢?解决这个问题我好费神,因为x64上不同优化等级这个问题答案也不同。
4. 多用编译期常量比较操作,少用偏特化。实际要考虑的组合千变万化,于是我尽量把ABI上的组合变化放在了内嵌汇编部分,这个部分已经没有了类型信息,我就痛痛快快的做常量比较 if else了,O0优化也会帮你干掉那些不需要的语句。
5. 苹果MAC操作系统是21世纪才使用x86和x64的,x86的ABI和linux有点点轻微的差异,主要在long double和函数调用堆栈对齐上。
6. GCC内嵌汇编上的支持好勉强,我定义寄存器变量却总是收到未初始化就使用的警告;我已经在内嵌汇编中ret了,却总是警告我没有给返回值。。吐槽点满满的,洒满一身。为了避免给使用者在-Wall的时候产生很多警告,我也用了很多黑科技手段去避免警告还不让性能有任何指令级的损失。
7.尽量避免C++模版编译结果体积膨胀:类型聚合(type union)(自己的C++小工具系列5) - 知乎专栏 类型聚合是个好方法,让我实现了用内嵌汇编去返回C++引用还不引起任何编译器警告。有兴趣的同学可以去瞅瞅源码。
8. 接下来的计划是支持lambda。因为好多人建议不仅仅是需要支持call_in_stack for function, 而是要让一大块代码都能整体在一个新的stack执行。考虑到lambda的ABI是没有公开的,打算做个wrapper去实现。