如何有效地调试constexpr功能?

fen*_*fen 15 c++ debugging constexpr c++11 c++14

在C++ 14中,我们获得了升级版本的constexpr含义,现在可以使用循环,if语句和开关.像C++ 11一样,递归已经成为可能.

我知道constexpr函数/代码应该很简单,但问题仍然存在:如何有效地调试它?

即使在" The C++ Programming Language,4th Edition "中也有一句话,调试可能很难.

Tem*_*Rex 6

调试constexpr功能有两个重要方面.

1)确保他们计算出正确的结果

在这里,您可以使用常规单元测试,断言或运行时调试程序来逐步执行代码.与测试常规功能相比,没有什么新东西了.

2)确保可以在编译时对它们进行评估

这可以通过将函数评估为constexpr变量赋值的右侧来测试.

constexpr auto my_var = my_fun(my_arg);
Run Code Online (Sandbox Code Playgroud)

为了使其工作,my_fun可以a)只有编译时常量表达式作为实际参数.即,my_arg是文字(内置或用户定义)或先前计算的constexpr变量或模板参数等,并且b)它只能constexpr在其实现中调用函数(因此没有虚函数,没有lambda表达式等).

注意:在constexpr函数的编译时评估期间,实际调试编译器的代码生成实现非常困难.您必须将调试器附加到编译器,并且实际上能够解释代码路径.也许某些未来版本的Clang会让你这样做,但这对现有技术来说是不可行的.

幸运的是,因为您可以解耦constexpr函数的运行时和编译时行为,所以调试它们的难度不如调试模板元程序(只能在编译时运行)的一半.

  • 大!所以基本上你可以在运行时使用"正常"调试,然后只确保它在编译时正确计算.我希望constexpr能让元编程变得更容易.我认为这是C++ 1y的一个很棒的功能 (3认同)
  • @fen 是的,我就是这样做的。它比模板元编程要容易得多。例如,一个 `constexpr` `switch` 语句等价于 TMP 中的几个类模板特化。它大大减少了必须维护的代码行数,并且您始终可以选择使用运行时参数运行相同的代码。 (2认同)
  • 为此,我是 `static_assert` 的粉丝。它检查值 _and_ 要求在编译时计算它。示例:`static_assert(my_fun(my_arg)==42", "my_fun(my_arg) 失败")` (2认同)