cpp-expert/constexpr-compile-time:constexpr 编译期计算演示
本目录收录 languages/cpp/expert/constexpr-compile-time.md 的完整可运行代码与实测数据。
要回答的问题:constexpr 真的在编译期算完吗?怎么强制它"必须在编译期算"?代价有多大?
| 文件 | 说明 |
|---|---|
main.cpp | 演示源码:fact 查表 + static_assert + 模板实参/枚举/数组大小三处强制编译期 |
deep.cpp | 深递归压力测试:fib(32) 编译期求值(观察编译期成本) |
Makefile | make run 运行;make asm 看 -O2 立即数折叠;make ctime 对比编译耗时;make ftime 看明细 |
run-remote.sh | 服务器一键实测脚本(产出本文全部数据) |
probe.sh | 临时探测脚本(fib(35/40/44) 编译耗时,供参考) |
编译与运行
bash
make # g++ -O0 -g -Wall -Wextra -std=c++11(旧编译器也可跑,行为与标准版本无关)
make run # 运行,打印编译期算好的值
make asm # -O2 反汇编:printf 参数全是立即数,运行期无 fact 调用
make ctime # 对比 main(浅)vs deep(深)的编译耗时
make ftime # deep 的 -ftime-report 明细实测输出(Linux, g++ 4.8.5, -std=c++11)
运行输出
5! = 120
12! = 479001600
7! = 5040
slot.size() = 720
MAX_ITEMS = 24-O2 反汇编(main 的 printf 调用处)
movl $120, %esi ← 5! 直接是立即数
movl $.LC0, %edi
xorl %eax, %eax
call printf
movl $479001600, %esi ← 12! 立即数
movl $720, %esi ← slot.size() 编译期就是 720
movl $24, %esi ← MAX_ITEMS 立即数
call printf运行期只有 printf 调用,没有任何 fact 函数调用——全部数值在编译期定案。
编译耗时对比
== main.cpp(浅:fact 表) ==
real 0m0.086s
== deep.cpp(深:fib(32) 编译期求值) ==
real 0m0.082s探测更高深度:fib(35)/fib(40)/fib(44) 编译均为约 0.08s——GCC 对 constexpr 求值带记忆化缓存,指数级递归并不会让编译时间爆炸。
deep.cpp 编译明细(-ftime-report 摘要)
template instantiation : 0.03 (38%) usr 0.02 (29%) sys 0.04 (25%) wall 4092 kB (20%) ggc
TOTAL : 0.08 0.07 0.16 20788 kBconstexpr 求值计入模板实例化阶段;真正让编译变慢的大头在模板元编程组合(见 template-instantiation 演示)。